首页
学习
活动
专区
圈层
工具
发布

GCC汇编
EN

Stack Overflow用户
提问于 2016-10-12 23:47:37
回答 1查看 225关注 0票数 0

我试图通过示例学习汇编语言,或者用-S选项编译简单的C文件,使用intel语法,并禁用CFI调用(其他任意方式都是非常混乱的)。

我的C文件实际上就是int main() {return 0;},但是GCC说:

代码语言:javascript
复制
    .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)?

总括而言,为何不是这样呢?

代码语言:javascript
复制
.def _main
_main:
mov eax, 0 ;(for return integer)
ret
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2016-10-13 01:08:17

GCC说了这句话

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

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

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

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

它正在设置一些您没有做的事情(但那些非平凡的程序会做),并且没有做它所能做的最优化的“返回0”程序。通过拥有一个基本指针(主要是原始堆栈指针的备份),程序可以自由地将局部变量作为偏移量加上基指针(包括参数计数、指向参数列表指针的指针和指向环境的指针等不使用的隐含内容),通过拥有16倍的堆栈指针,程序可以根据其调用标准自由地调用函数。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/40010107

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档