Windows x86-64 Assembly Output question [SOLVED]

Context

I am learning Windows x86-64 Assembly and its ABI Conventions.

I wrote some code in Rust and C to test returning Larger Structs "by-value" to see how they handle it.

Below, I have included Source Code and the generated Assembly.

I compiled both programs with optimizations enabled and with debug info.

Here are the Compilers I used:

compilers

Issue

I wrote the following code in Rust and C:

struct-crust

Here is the assembly output, as seen in the debugger (with the differences highlighted green):

struct-asm

As you can see, the generated code is nearly the same.

However, the Rust code writes a second copy of the return value to the stack (and moves the stack pointer back and forth) in addition to returning it by register (which is how it should be returned).

Question

Are the extra instructions in the Rust version the result of a miscompilation?

Or is this a result of something ABI / Debug Info / etc... -related that I am unaware of?

Have you compiled with --release? Rust generates absolutely awful inefficient slow code by default, unless you build with optimizations.

With optimizations enabled it seems to be just two movs:

The code seen on Compiler Explorer is (most likely) not running on a Windows machine. (It's to my understanding that they are compiled/run on Linux for most cases)

The Windows x64 ABI is different than the Linux / OS X x64 ABI, to my understanding.

The code shown on Compiler Explorer would not be valid for a Windows program.

That being said, I am fairly certain I did compile with --release.

The compiler explorer can build for other targets. With MSVC target I get the exact code as your C version:

        mov     rax, rcx
        mov     qword ptr [rcx], rdx
        mov     qword ptr [rcx + 8], r8

If you've built with optimizations, then I don't know what happened that caused the extra instructions. Your code seems fine, with the right repr and ABI.

1 Like

I see. I didn't know that was a feature (thanks!).

(As a side note, it appears that the Target Architecture is not saved as part of the link)

Upon doing some more extensive testing, it would appear that in spite of adding "--release" to the flags in the VS Code debug launch configuration settings file, I was actually still running in Debug Mode earlier, somehow.

My apologies for not catching that sooner.

Thank you for your time.

EDIT: As it turns out, clicking the "Debug" above the main function in VS Code is not the same as clicking "Debug and Run" in the sidebar menu. (The sidebar uses the --release setting I added, whereas the Debug button does not), hence the confusion.

1 Like

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.