[英]Understanding gcc -S output
我在 x86_64 上的下面非常复杂的程序上做了 gcc -S:
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()
,对吗?
这些.cfisomething
指令会导致编译器生成额外的数据。 当指令导致异常时,此数据有助于遍历调用堆栈,因此可以找到并正确执行异常处理程序(如果有)。 调用堆栈信息对于调试很有用。 该数据很可能进入可执行文件的单独部分。 它不会插入您的代码指令之间。
.LFsomething:
只是可能被额外的异常相关数据引用的常规标签。
leave
和ret
是 CPU 指令。
leave
相当于:
movq %rbp, %rsp
popq %rbp
它会撤销这两条指令的效果
pushq %rbp
movq %rsp, %rbp
和通过从rsp
减去一些东西来分配堆栈空间的指令。
ret
从函数返回。 它从堆栈中弹出返回地址并跳转到该地址。 如果是__libc_start_main()
调用了main()
,那么它会返回那里。
.LFB0, .LFE0
是本地标签。
.cfi_startproc
用于每个函数的开头,函数的结尾是.cfi_endproc
。
leave
指令是一条 x86 汇编指令,它负责恢复调用函数的堆栈帧。
最后在ret
指令之后,发生了以下事情:
%rip
包含返回地址%rsp
指向调用者推送的参数,这些参数不适合用于在 amd64 上传递参数的六个寄存器(%rdi、%rsi、%rdx、%rcx、%r8、%r9)%rax
包含返回值(如果函数为 void,则为垃圾)(或%rax
和%rdx
包含返回值,如果其大小大于 8 字节但 <=16 字节1 )%r10
, %r11
可能被丢弃%rbp
, %rbx
, %r12
, %r13
, %r14
, %r15
必须包含调用时的内容可以在此处(SO 问题)和此处(标准 PDF)找到其他信息。
或者,在 32 位上:
%eip
包含返回地址%esp
指向调用者推送的参数%eax
包含返回值(如果函数为空则为垃圾)%ecx
, %edx
可能被丢弃%ebp
, %ebx
, %esi
, %edi
必须包含调用时的内容
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.