简而言之,我正在研究Singh和Triebel的一本名为"8088和8086微处理器"的书,以学习那些特定CPU的旧组件.现在,我正在练习的计算机是我最近构建的主计算机,因此寄存器更大.
也就是说,这本书(我觉得非常有用)说调用标签操作数会导致调用后的指令地址被放在堆栈上,然后THEN SP递减2(ESP并在我的CPU上递减4) .在我正在研究的一些代码中,一个调用操作数后面紧跟一个push.当CPU遇到a时push,书中说明SP会减2(再次,ESP在我的CPU上减4).
; ESP=0xffffd840 right now
call iprint
mov eax, 0Ah
iprint:
push eax ; say eax contains 1
Run Code Online (Sandbox Code Playgroud)
现在,ESP=0xffffd840在通话前说.地址EIP保存在堆栈中(CALL操作数后面的指令地址).然后ESP减少4.此时,ESP=0xffffd83c.然后遇到推送操作数.按照本书所说的,首先递减堆栈指针,然后将寄存器的内容压入堆栈.所以现在ESP=0xffffd838,1被推入堆栈.
If it helps:
Stack addr Contents
********** ********
0xffffd840 address of mov eax, 0Ah
0xffffd83c ?
0xffffd838 1
Run Code Online (Sandbox Code Playgroud)
现在,我的问题是,0xffffd83c跳过了吗?根据这本书,ESP在保存下一条指令之后递减call,然后在数据从堆栈中放入之前push,它再次递减.
我一直在调试类似的情况一段时间,密切注意寄存器的值,但我无法判断调试器是否符合本书所说的内容(在执行操作之前或之后递减).
这是因为在某些情况下,RET在子程序之后给出一个参数,导致堆栈指针递增?如果堆栈指针在放入数据之前确实递减了两次,这是我能看到的唯一原因.
如果我有这个错误,有人可以确认或解释一下吗?
谢谢