0

I am in the beginning of learning intel's x86 assembly code and compiled this simple "hello world" c program (without the cfi additions for simplicity): #include

int main(int argc, char* argv[]) {      

    printf("hello world!");
    return 0;
}

The following x86 code came out:

.file   "helloworld.c"
.intel_syntax noprefix
.section    .rodata
.LC0:
.string "hello world!"
.text
.globl  main
.type   main, @function
main:
push    rbp
mov rbp, rsp
sub rsp, 16
mov DWORD PTR -4[rbp], edi
mov QWORD PTR -16[rbp], rsi
lea rdi, .LC0[rip]
mov eax, 0
call    printf@PLT
mov eax, 0
leave
ret
.size   main, .-main
.ident  "GCC: (Debian 7.2.0-19) 7.2.0"
.section    .note.GNU-stack,"",@progbits

The question: Why are those 16 bytes for local variables reserved on the stack but aren't used in any way? The program even does the same, without those lines, so for which reason were they created?

Jabberwocky
  • 48,281
  • 17
  • 65
  • 115
Kranta
  • 1
  • 1
    You forgot to enable optimization. Even so, you will still have padding for alignment. See the calling convention documentation. – Jester Mar 09 '18 at 12:19
  • 3
    12 of the bytes are used to spill `argc` and `argv`; notice the two stores. They're dead stores because you compiled in debug mode, but that's the whole point of debug mode: keep everything in memory. – Peter Cordes Mar 09 '18 at 12:25
  • thx, I understand. How can I compile it optimized? Using -o didn't help. And if 12 bytes are used for argc and argv, what are the other 4 bytes for? – Kranta Mar 09 '18 at 12:33
  • Use `-O2` (capital letter). As I said, calling convention mandates alignment, so you may still have unused padding bytes. – Jester Mar 09 '18 at 12:41
  • thanks guys, you helped me a lot :) – Kranta Mar 09 '18 at 12:58
  • @PeterCordes Shouldn't those 12 bytes for function parameters be reserved before calling `main`? Aren't they addressed using `rbp+x` while local variables are stored at `rbp-x` – Gerhardh Mar 09 '18 at 13:08
  • @Gerhardh: They're passed in registers. x86-64 calling conventions pass the first few integer args in registers, unlike some crappy obsolete 32-bit calling conventions that pass all the args on the stack. In this case, it's the x86-64 System V ABI. https://stackoverflow.com/questions/18133812/where-is-the-x86-64-system-v-abi-documented – Peter Cordes Mar 09 '18 at 13:09
  • @PeterCordes OK, I see. Thanks – Gerhardh Mar 09 '18 at 13:10
  • @Gerhardh As far as I understand argc and argv are still treated like parameters and parameters are reserved in the callee and main is the callee in this situation. – Kranta Mar 09 '18 at 13:10
  • Args that couldn't be passed in registers are placed on the stack by the caller, but they're *owned* by the callee (i.e. functions are allowed to modify their args on the stack). So in that case, they can't be "reserved" by the callee. In both normal x86-64 calling conventions, the caller is responsible for un-reserving the the arg-passing space after the callee returns, though. – Peter Cordes Mar 09 '18 at 13:13

0 Answers0