目前,我正在学习高级汇编语言,并且已经研究了堆栈的概念。我认为我理解得很好,但是实际上我有一些疑问。

堆栈向下扩展,ESP寄存器始终指向堆栈的顶部。低内存中的地址。如果将某些东西压入堆栈,则应减小ESP。

EBP用作帧指针,据我所知,应该始终大于ESP。

但是,使用以下程序:

stdout.put(esp, nl);
stdout.put(ebp, nl);
push(ike);
stdout.put(esp, nl);
stdout.put(ebp, nl);
push(ike);
stdout.put(esp, nl);
stdout.put(ebp, nl);
pop(eax);
pop(eax);
pop(eax);
pop(eax);
stdout.put(esp, nl);
stdout.put(ebp, nl);


似乎并非如此。查看输出:

0018FF6C
0018FF70

0018FF68
0018FF70

0018FF64
0018FF70

0018FF74
0018FF70

EBP始终相同,ESP在第一次推送时递减4个字节,然后在第二次推送时递减4个字节。

在这之后我感到困惑。在我的前2个弹出窗口之后,ESP应该回到它的开始位置。如果我还没有将任何东西压入堆栈,该如何再进行两次弹出?我在弹出什么?

从EAX进一步弹出并打印会显示一些数字,然后是0,再是其他数字。所以,我绝对是在弹出某事...但是呢?它属于程序存储器的哪一部分,为什么什么都没有受到影响?

为什么EBP根本不受影响?

另外,为什么ESP递减4个字节而不是8个字节?

如果有人可以帮助我理解这一点,我将不胜感激。

最佳答案

EBP不会通过推送/弹出指令进行修改,它是手动设置的,因此,除非您自己进行更改,否则它将保持不变。

IKE的推动导致4字节的更改,因此显然您在此处处于32位模式。

就像它们一样,EAX(32位)的4次弹出将导致16字节(10h)的更改。

不知道这里出了什么问题。似乎按我的预期工作?

关于assembly - 从栈中弹出而没有按下,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/7174983/

10-11 23:21
查看更多