【发布时间】:2017-10-09 12:45:33
【问题描述】:
_main:
; create stack frame
pushl %ebp
movl %esp, %ebp
; save one local variable
subl $8, %esp
; zero four rightmost bits of esp
andl $-16, %esp
; set eax to (0 + 15 + 15) / 2^4 * 2^4 = 16
movl $0, %eax
addl $15, %eax
addl $15, %eax
shrl $4, %eax
sall $4, %eax
; set local variable to eax (16)
movl %eax, -4(%ebp)
movl -4(%ebp), %eax
; call allocation and main
call __alloca
call ___main
; set eax to zero (return value)
movl $0, %eax
; fold stack frame and return to caller
leave
ret
我使用gcc -S return_zero.c(在Windows上)编译了int main(){return 0;} C代码,这就是我得到的(我删除了汇编程序指令并添加了我所理解的解释注释。如果我错了,请纠正我.)。
我不明白三件事:
- 为什么编译器将 esp 对齐到 16?
- 为什么eax设置为16,为什么做的这么复杂,为什么还有一个局部变量也设置为16?
- 什么是 __alloca 和 ___main?
我在互联网上对#1和#3都有一些不清楚的解释,所以我想如果有人可以更深入地回答,对于#2我没有找到任何解释,所以如果有人可以解释它会很棒.
如果需要任何进一步的信息,请发表评论,我会发布。
谢谢!
【问题讨论】:
-
尝试优化编译。
-
@KerrekSB 我用 -O3 编译。它删除了整个 eax = 16 的东西,并在最后使用 xorl 而不是 movl 将 eax 设置为 0,但它仍然执行所有其他操作(包括声明局部变量)。我也很好奇它为什么会这样做。
-
这是用于什么平台的?我无法在 Linux 上重现它。
-
@KerrekSB 我正在使用带有 Intel Core i5 的 Windows 8.1。
-
检查 Windows ABI,特别是注册溢出和红色区域。
标签: c gcc assembly compiler-construction x86