2017-08-15 243 views
2

我无法找到答案。从我读过的%ebp有32位,将%esp移动到%ebp,你仍然会有32位,然后减去70到32,我不明白其余的。我对此很陌生,所以我不是很精通。请给出详细的解释。谢谢!查找有多少字节将esp和程序堆栈上存储的返回地址分开

下面是我遇到的问题。

在这个指令序列的末尾,多少个字节将esp和程序堆栈上存储的返回地址分开?假设我们使用标准的32位x86调用约定来调用这个函数。

804847c functioname: 
804847c: push %ebp 
804847d: mov %esp,%ebp 
804847f: sub $0x70,%esp 
8048482: movl $0x0,0x4(%esp) 
804848a: movl $0x8048580,(%esp) 
+0

此指令子$ 0x70,%esp中的$ 0x70值被符号扩展为32位,所以它也有32位,就像'esp'和'ebp'一样。 (尽管内部0x70值在指令中只编码了8位,但这不是它的使用方式,这只是在这种特殊情况下的存储优化)。使用的比特数限制了可以在那些比特中编码的不同值的数量,即8比特可以被解释为从0到255,或从-128到+127,或者作为八个1比特标志(开/关)的值。在你的问题中,这并不重要,因为所有涉及的值都是32b。 – Ped7g

回答

1

sub $0x70,%esp:在堆栈上保留0x70个字节。

movl $0x0,0x4(%esp):放置一个零32位值作为参数。

movl $0x8048580,(%esp):发表地址。下一个ret会跳到它。

通过标准调用约定,名为cdecl,参数被放置在堆栈上,后面跟着被调用者应该返回的地址。

+1

这看起来不对。 _ESP_已经向下调整了0x70(112字节)。 'sub'指令后,_EBP_的临时副本位于_ESP_ + 0x70,返回地址位于_ESP_ + 0x74。 0x04(%esp)和(%esp)实际上指向使用'sub $ 0x70,%esp'指令在堆栈上创建的局部变量区域 –

+2

在我看来,实际问题的答案是_ESP_和返回地址是0x70 + 0x04(推送_EBP_时为4个字节)。它是十进制的116或十六进制的0x74。 –

+1

应该指出'movl'指令 - 我们不知道它们打算用于什么。他们实际纳入问题实际上并没有改变_ESP_和返回地址之间的差异。他们实际上只是一条红鲱鱼。这听起来像一个家庭作业的作业,导师很可能会混淆学生最后2条指令。 –