'In Assembler AT&T context: What does movl do in this specified line?

i have a some simple lines of code in C and wanted to disassemble it:

#include <stdio.h>
int main(){
  int i=42;
}

After compiling it and starting gdb, i simply cant find my value=42 in the corresponding place: enter image description here

Its not just that i get the value 0, but what exactly does

movl $0x2a, -0x4(%rbp)

mean. I know that 0x2a is 42 in hex, but the next part is cryptic to me; should it mean, that 42 gets saved into register rbp ? and what about the -0x4? And where is my 42 :O ?



Solution 1:[1]

Each variable in C either gets a set position in memory (called the stack) or a register. In fact, the compiler will often move variables between these two places for performance.

MOVL moves a 32-bit number (your int!) from one register to another, while MOV moves an entire register, even if your program doesn't use that part of the register.

PUSH and POP add and remove items from the stack. It's often used by the C compiler to save registers. As a function calling main(), you have no idea what it does, and how to clean up after all the memory main() uses, which is why it is main()'s responsibility to clean up after itself, leaving the program exactly as it started with it. (except, of course, for the results of the operation)

EAX is a common register, and is typically used for the results of functions.

With this background, let's rewrite your program in a slightly more readable form:

  1. push %rbp Move the stack pointer to the stack itself (so we can clean up after all of our junk memory)
  2. mov %rsp, %rbp Resize the stack to 0, Preventing the main() from accidentally reading junk from other functions
  3. movl $0x2a, -0x4(%rbp) Move 42 to the first slot in the stack (note: Since an int is 4 bytes big, this is actually the -4th space!)
  4. Wait-- We never actually resized the stack to tell other programs that our special number is there. This is because the compiler optimized it away, as it saw that we were increasing the size when we were going to reset it in a few instructions anyways.
    • Thank you Peter Cordes, for reminding me the Red Zone exists! This is a special area of memory inside of the stack which does not require the stack to be expanded before writing to it. In the case of this program, this is likely what is happening.
  5. MOV $0x0, %eax Move 0 to the result register (EAX)
  6. POP %RBP Clean Up after our mess by restoring the old stack pointer. This means that, even though we reset the size of the stack, the program above us will still have all of their memory intact. Remember--We did this to prevent main() from accessing other function's memory. Great!
  7. RETQ Return and say goodbye ;(

If you wanted to retrieve your 42, you would need to change your code to say return 42, which would means the compiler would place 42 in EAX, and it would get passed up to your friends above :)

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1