x86 $ esp奇怪地改变

时间:2012-02-27 06:00:31

标签: assembly x86

我正在拆解一些用GCC编译的x86汇编代码以进行赋值。

在调用函数之前,我有:

$esp = 0xffffdbd0

在被调用函数的第一行(甚至在push之前)设置断点:

$esp = 0xffffdbcc

推后:

$esp = 0xffffdbc8

那么为什么$esp会改变呢?从理论上讲,只是去一个函数不应该改变堆栈指针,然后它会在push之后改变?发生了什么事?

我有一个猜测,它与对齐有关,并且在某种程度上,使用callpush汇编指令在我背后进行某种对齐。但这是一个猜测;我不知道。

知道澄清的人可以吗?

3 个答案:

答案 0 :(得分:4)

执行CALL指令时,紧跟CALL之后的指令地址被压入堆栈。这样,当您执行RET指令时,程序可以跳回到正确的地址并继续执行指令。将此地址压入堆栈意味着您可以嵌套CALL并且在每个RET返回正确的地址时没有问题。

由于这是一个32位系统,因此将4个字节压入堆栈:

0xffffdbd0 - 0xffffdbcc = 0x4

答案 1 :(得分:3)

call指令在跳转到目标位置之前将第一条指令的地址推送到堆栈。这样,ret知道函数返回后的去向。

答案 2 :(得分:2)

你的假设

  

理论上,只是去一个函数不应该改变堆栈   指针

是完全错误的。转到一个函数就是这样:它改变了堆栈指针,特别是它推送了返回地址。在x86中(以及几乎所有其他拱门中)“推送”总是意味着隐式递减堆栈指针并存储要在其上推送的值。