GCC汇编汇编

时间:2016-10-12 23:47:37

标签: gcc assembly x86 intel

我试图通过示例学习汇编语言,或者使用-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"

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

总结一下,为什么不是这样呢?

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

1 个答案:

答案 0 :(得分:0)

  

海湾合作委员会吐出这个

如果您确实让主函数做了一些事情,奇怪的是,包括调用另一个函数,这可能会更清楚一些。

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

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

  

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

它为你不做的事情设置了东西(但那些重要的程序会这样做),并没有做出最优化的"返回0"程序,它可以。通过使一个基本指针主要是原始堆栈指针的备份,程序可以自由地将局部变量称为偏移量加上基本指针(包括你不使用的隐含的东西,如参数计数,指针指向参数列表的指针和指向环境的指针,并且通过具有16的倍数的堆栈指针,程序可以根据其调用标准自由地调用函数。

相关问题