问题描述
我在下面的x86_64上非常复杂的程序上做了gcc -S:
I did gcc -S on the very complex program below on x86_64:
int main() {
int x = 3;
x = 5;
return 0;
}
我得到的是:
.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
我在想,是否有人可以帮助我理解输出或使我参考一些链接说明.具体来说,cfi ,LFB0,LFE0 , leave
是什么意思?我所能找到的关于这些的是这篇文章但无法完全理解它的用途.另外,在这种情况下ret
会做什么?我猜它正在返回到__libc_start_main()
,这反过来又叫do_exit()
,对吗?
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?
推荐答案
那些.cfisomething
指令导致编译器生成其他数据.当指令导致异常时,此数据有助于遍历调用堆栈,因此可以找到并正确执行异常处理程序(如果有).调用堆栈信息对于调试很有用.此数据最有可能进入可执行文件的单独部分.不会在您的代码说明之间插入它.
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:
只是常规标签,可能被这些额外的异常相关数据引用.
.LFsomething:
are just regular labels that are probably referenced by that extra exception-related data.
leave
和ret
是CPU指令.
leave
等效于:
movq %rbp, %rsp
popq %rbp
并且取消了这两个指令的作用
and it undoes the effect of these two instructions
pushq %rbp
movq %rsp, %rbp
以及通过从rsp
减去一些东西来分配堆栈空间的指令.
and instructions that allocate space on the stack by subtracting something from rsp
.
ret
从函数返回.它从堆栈中弹出返回地址并跳转到该地址.如果是__libc_start_main()
调用了main()
,那么它将返回那里.
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.
这篇关于了解gcc -S输出的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!