2

This is the rust code I've written in the Compiler Explorer:

fn foo(a: u8, b: u8) -> u8 {
    let sum: u8 = a + b;
    sum
}


fn main() {

    let x = 4;
    let y = 6;
    let _t = foo(x, y);
}

I can't understand the assembly code generated for this piece of code. For instance, the assembly for the foo function is this:

example::foo:
 push   rax
 mov    cl,sil
 mov    al,dil
 add    al,cl
 mov    BYTE PTR [rsp+0x7],al
 setb   al
 test   al,0x1
 jne    7ada <example::foo+0x1a>
 mov    al,BYTE PTR [rsp+0x7]
 pop    rcx
 ret    

From my background in assembly and C, at the beginning of a function call, it should push the base pointer on the stack, and then mov the stack pointer to the base pointer. I expected it to be started with some thing like this:

 push   rbp
 mov    rbp,rsp

But it pushes the rax which I don't understand why. What is the difference between assembly code generated by the Rust compiler with assembly code generated by gcc or llvm for C or C++?

Is there any resource to learn more about assembly code generated by the Rust compiler?

This is link of my snippet on compiler explorer.

Peter Cordes
  • 328,167
  • 45
  • 605
  • 847
Amir reza Riahi
  • 1,540
  • 2
  • 8
  • 34
  • from what I can see, rust see that for a small function like this, the function don't need to save the stack frame and can just use the registers to do what it needs. the push rax instruction must just be to save what is in that register, its popped back into rcx afterward. – Bamontan Aug 19 '22 at 16:04
  • @Bamontan, The same is true for the `main` function. – Amir reza Riahi Aug 19 '22 at 16:06
  • yes, but the main function also don't store anything on the stack, so it does'nt need to create a stack frame – Bamontan Aug 19 '22 at 16:08
  • @Bamontan So you mean this is kinda optimization technique used by rust compiler? And if I try to create more variables (more than registers) it would do as I expected? – Amir reza Riahi Aug 19 '22 at 16:10
  • I think yes, I just created an array of 30 i32 in the foo function, at the beggining of the function 136 is substracted to rsp to make room on the stack for it, its then added back at the end of the function. – Bamontan Aug 19 '22 at 16:15
  • 1
    *"So you mean this is kinda optimization technique used by rust compiler?"* - well, more like its not doing work that's unneeded. This assembly was generated with optimizations *off*, even more melts away if they are on: [godbolt link](https://godbolt.org/z/zvnG95Tf6) – kmdreko Aug 19 '22 at 18:26
  • I guess you've only ever looked at un-optimized C compiler output? Yuck. [How to remove "noise" from GCC/clang assembly output?](https://stackoverflow.com/q/38552116) `-fomit-frame-pointer` is on by default in GCC and clang at `-O1` / `-Og` and higher. Although not in `-Os`, IIRC. – Peter Cordes Aug 19 '22 at 18:34

0 Answers0