GCC编译汇编

我尝试通过示例学习汇编语言,或者使用-S选项,英特尔语法和CFI调用禁用(使用其他免费方式非常混淆,使用GCC编译简单C文件)

我的C文件实际上只是int main() {return 0;} ,但GCC吐出这个:

    .file   "simpleCTest.c"
    .intel_syntax noprefix
    .def    ___main;    .scl    2;  .type   32; .endef
    .text
    .globl  _main
    .def    _main;  .scl    2;  .type   32; .endef
_main:
    push    ebp
    mov ebp, esp
    and esp, -16
    call    ___main
    mov eax, 0
    leave
    ret
    .ident  "GCC: (GNU) 5.3.0"

我真正的问题是为什么主函数有任何处理器指令( push edpmov edp, esp等)? 这些甚至是必要的(我猜这将是一种数据管理来准备/关闭程序,但我不确定)? 为什么不在主函数之后发出ret语句? 还有为什么有两个主要功能(_main&___main)?

总而言之,为什么它不仅仅是这样?

.def _main
_main:
mov eax, 0 ;(for return integer)
ret

GCC吐出这个

这可能会更清楚一点,如果你真的让你的主要功能做了一些奇怪的事情,包括调用另一个函数。

您的编译代码设置了一个框架,通过该框架可以通过第一个操作码mov ebp,esp引用其堆栈变量。 例如,如果您有可以用ebp和常量引用的变量,则可以使用这种方法。 然后,使用AND指令将堆栈对齐到16个字节的倍数,也就是说,它将不会使用所提供的堆栈的0到15个字节,因此[esp]被对齐到16的倍数字节。 由于使用的调用约定,这一点很重要。

结束操作码将备份的基本指针复制到堆栈指针的当前状态,然后使用弹出来恢复原始基本指针。

我真正的问题是为什么主函数有任何处理器指令

它为你不做的事情设置了东西(但是那些不重要的程序会这样做),并且没有做出它可能的最优化的“return 0”程序。 通过拥有一个基本指针,该指针大多是原始堆栈指针的备份,程序可以自由地将局部变量作为偏移量加上基本指针(包括默认的东西,例如参数计数,指向指向参数列表的指针以及指向环境的指针),并且具有16的倍数的堆栈指针,程序可以根据其调用标准自由调用函数。

链接地址: http://www.djcxy.com/p/86795.html

上一篇: GCC compiled assembly

下一篇: Does AT&T syntax work on intel platform?