While fiddling with the new inline assembly syntax, I noticed that the compiler was adding a push rax
at the beginning of my function and a corresponding pop rcx
at the end. Why is it doing that? How can I suppress the generation of those instructions?
I’m using rustc nightly to compile a simple function that adds 5 to its argument:
pub fn asm_add_five(n: u64) -> u64 {
let mut result;
unsafe {
asm!(
"lea {result}, [{n} + 5]",
n = in(reg) n,
result = out(reg) result,
);
}
result
}
The generated assembly looks like this:
example::asm_add_five:
push rax
lea rax, [rdi + 5]
pop rcx
ret
I normally compile with -Ctarget-feature=+sse,+sse-unaligned-mem,+sse2,+sse3,+ssse3,+sse4.1,+sse4.2 -Cdebuginfo=2 -Copt-level=3 -Ccodegen-units=1 -Clto=fat
.
You can run the code on Godbolt. There is also a native Rust add_five() function there for comparison.
I’m new to Rust and to x86 assembly and I’d be happy to read any foundational books or documentation that can clarify this.