2014-01-13 13 views
2

我看过的汇编代码的一些转储和有这部分(发现herehere)的主要功能:为什么这个函数序言使用几条指令来计算esp的减少?

<main+0>: push %ebp 
<main+1>: mov %esp, %ebp 
<main+3>: sub $0x8, %esp 
<main+6>: and $0xfffffff0, %esp 
<main+9>: mov $0x0, %eax 
<main+14>: add $0xf, %eax 
<main+17>: add $0xf, %eax 
<main+20>: shr $0x4, %eax 
<main+23>: shl $0x4, %eax 
<main+26>: sub %eax, %esp 

你能解释我什么(主+ 9)(主+ 26 ) 是用来? 为什么这样做'低效'?

+0

是由gcc在2004年生成的代码?快乐的日子过去了!即使是最笨重的优化器也应该能够编写更好的main + 9到main + 26的代码。 – ShinTakezou

+0

生成此程序集的输入(C代码?)是什么?什么是编译器版本和标志? –

+0

[gcc在windows上产生垃圾的可能重复? windows vs linux](http://stackoverflow.com/questions/19552816/gcc-on-windows-generating-garbage-windows-vs-linux)同样的序幕。他们说这只发生在Windows和GCC 3.X上,在那里和'alloca'生成。 –

回答

2

所以你想要一个完整的漫步而不做任何研究自己?听起来像是对的。

主+ 9:MOV $为0x0,%eax中

加载寄存器eax十六进制0(=分解0)。

主+ 14:加$ 0xf,%eax中

添加六角˚F(= 12月15日),以在eax零。

主+ 17:加$ 0xf,%eax中

再次添加六角˚F(= 12月15日),以eax。这三个指令可能也受到

movl $0x1e, %eax 

但谁的票的指令......总之,在这一点上eax包含六角完成1E这是十二月30

主+ 20 :SHR $为0x4,%EAX

由四位移位eax向右内容。

主+ 23:SHL $为0x4,%EAX

班次eax右后卫。为什么?因为这会清除最低的四位。现在EAX包含十六进制10(= 12月16日)

主+ 26:子%eax中,尤指%

Substracts从espeax(堆栈指针)。由于

主+ 6:和$ 0xfffffff0,%ESP

清除低四位在esp以前,新esp将是十六字节对齐,按照ABI。为什么不简单地在main+6之后使用esp?因为在x86上,该堆栈从内存顶部向下增长。简单地掩盖esp的低位可能会破坏局部变量。因此,减法将堆栈减小到到十六字节边界。

+1

感谢您的walktrough。但不能主+ 9到主+ 26是由sub $ 0x10,%esp? –

+0

@ red-E:是的。这确实是非常可怕的代码,它使用了比必要更多的指令。但它也是泛型代码:类似的代码用于分配可变长度的堆栈缓冲区,因此编译器可以重新使用代码。 – EOF

相关问题