I did gcc -S on the very complex program below on x86_64:
int main() {
int x = 3;
x = 5;
return 0;
}
And what I got was:
.file "main.c"
.text
.globl main
.type main, @function
main:
.LFB0:
.cfi_startproc
pushq %rbp
.cfi_def_cfa_offset 16
.cfi_offset 6, -16
movq %rsp, %rbp
.cfi_def_cfa_register 6
movl $3, -4(%rbp)
movl $5, -4(%rbp)
movl $0, %eax
leave
.cfi_def_cfa 7, 8
ret
.cfi_endproc
.LFE0:
.size main, .-main
.ident "GCC: (GNU) 4.4.7 20120313 (Red Hat 4.4.7-3)"
.section .note.GNU-stack,"",@progbits
I was wondering if someone could help me understand the output or refer me to some link explaining. Specifically, What does cfi ,LFB0,LFE0 , leave
mean? All I could find regarding these is this post but couldn't fully understand what it was for. Also, what does ret
do in this case? I'm guessing it's returning to __libc_start_main()
which in turn would call do_exit()
, is that correct?
Those .cfisomething
directives result in generation of additional data by the compiler. This data helps traverse the call stack when an instruction causes an exception, so the exception handler (if any) can be found and correctly executed. The call stack information is useful for debugging. This data most probably goes into a separate section of the executable. It's not inserted between the instructions of your code.
.LFsomething:
are just regular labels that are probably referenced by that extra exception-related data.
leave
and ret
are CPU instructions.
leave
is equivalent to:
movq %rbp, %rsp
popq %rbp
and it undoes the effect of these two instructions
pushq %rbp
movq %rsp, %rbp
and instructions that allocate space on the stack by subtracting something from rsp
.
ret
returns from the function. It pops the return address from the stack and jumps to that address. If it was __libc_start_main()
that called main()
, then it returns there.
Here you go :
1: .LFB0, .LFE0
are nothing but local labels.
2: .cfi_startproc
is used at the beginning of each function and end of the function happens by .cfi_endproc
.
3: the leave
instruction is an x86 assembler instruction which does the work of restoring the calling function's stack frame.
and lastly after the Ret instruction , following things happen
o %eip contains return address
o %esp points at arguments pushed by caller
o called function may have trashed arguments
o %eax contains return value (or trash if function is void)
o %ecx, %edx may be trashed
o %ebp, %ebx, %esi, %edi must contain contents from time of call