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:
Issue
I wrote the following code in Rust and C:
Here is the assembly output, as seen in the debugger (with the differences highlighted green):
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?
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.
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.
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.