7
votes

I'm trying to understand this simple C program:

int square(int num) {
    return num * num; 
}

When it's in Assembly code:

square(int): 
  push rbp ;push rbp register onto stack
  mov rbp, rsp ;move contents of rbp register into rsp register 
  mov DWORD PTR [rbp-4], edi ;not sure what happens here 
  mov eax, DWORD PTR [rbp-4] ;not sure what happens here
  imul eax, DWORD PTR [rbp-4] ;multiply eax and DWORD PTR [rbp-4] (?)
  pop rbp ;pop original register out of stack
  ret ;return 
  1. What is happening in the 3rd and 4th line?
  2. Why did two more register (edi and eax) have to be used instead of rsp?
  3. What is actually happening with DWORD PTR [rbp-4]?
1
Might I suggest you compile with optimizations on.Michael Petch
You forgot to enable optimizations hence all the extra stuff. It's just going through memory using a temporary variable at [rbp-4] With optimizations enabled that should reduce to mov eax, edi; imul eax, eax; ret.Jester
Your analysis of line two is wrong. In Intel Assembly syntax the first operand is the destination, the second one is the sourceUnholySheep
This is unoptimized code where the argument num in edi register is stored as local variable in the stack frame and copied back to eax register.Aki Suihkonen
godbolt.org/g/juws2k and experiment there0___________

1 Answers

9
votes
mov DWORD PTR [rbp-4], edi ;not sure what happens here

The x86_64 System V ABI passes function arguments via registers - the first integer argument is passed in the rdi/edi register. So this line copies the argument num to a local (offset -4 bytes from the frame pointer value stored in rbp).

mov eax, DWORD PTR [rbp-4] ;not sure what happens here

This copies the value in the local to the eax register.

imul eax, DWORD PTR [rbp-4] ;multiply eax and DWORD PTR [rbp-4] (?)

And this multiplies the value in eax by the local, and stores the result to eax (which also happens to be the register in which the function return value is stored).

As others pointed out in the comments, compiling with optimization would likely eliminate the local, and write directly from edi to eax.