繁体   English   中英

理解 gcc -S 输出

[英]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:只是可能被额外的异常相关数据引用的常规标签。

leaveret是 CPU 指令。

leave相当于:

movq    %rbp, %rsp
popq    %rbp

它会撤销这两条指令的效果

pushq   %rbp
movq    %rsp, %rbp

和通过从rsp减去一些东西来分配堆栈空间的指令。

ret从函数返回。 它从堆栈中弹出返回地址并跳转到该地址。 如果是__libc_start_main()调用了main() ,那么它会返回那里。

  1. .LFB0, .LFE0是本地标签。

  2. .cfi_startproc用于每个函数的开头,函数的结尾是.cfi_endproc

    • 这些汇编器指令帮助汇编器将调试和堆栈展开信息放入可执行文件中。
  3. 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM