为什么推送EBX会导致弹出ESI

时间:2019-01-21 13:42:22

标签: assembly x86

我拿起《实践逆向工程》这本书,在第14页(x86汇编)上有以下示例:

mov eax, 0AAAAAAAh
mov ebx, 0BBBBBBBh
push eax
push ebx
pop esi
pop edi

现在,我将eax和ebx推入堆栈,但是我弹出堆栈的esi和edi。这是为什么?我以为我会推送并弹出相同的寄存器。

3 个答案:

答案 0 :(得分:1)

您不推送寄存器,而是推送这些寄存器中保存的。在这种情况下,值来自寄存器DoCmd.OpenForm "frmService", acNormal, , "WorkOrderID = " & Me!txtID, acFormEdit eax。寄存器本身保留在原处(CPU内部的某个地方)。

您可以将这些值弹出到任何寄存器中,例如ebxesi。它仅取决于代码中的位置以及需要这些值的寄存器。

有时您只想从堆栈中清除一些值。然后你可以做

edi

那不会影响任何其他寄存器。(当然,您也可以简单地更改堆栈指针,但这是另一个主题。)

答案 1 :(得分:1)

当您pop堆栈时,寄存器操作数仅接收堆栈顶部的值。只要压入和弹出相同数量的字节,堆栈就会保持平衡,而不管字节在哪里。您不一定需要pop回到原来的值push所在的位置。

例如,此代码使用ecx中当前存在的内容加载寄存器eax,而不会导致堆栈未对齐:

push eax
pop ecx

您还可以通过手动调整堆栈指针来执行有效的“无操作数” pop

push eax
...
add esp, 4 ; Discard 32-bits on top of stack 
; Stack is now balanced (assuming the intermediate instructions did not misalign the stack)

答案 2 :(得分:0)

  

推入—推入堆栈

     

push指令将其操作数放在内存中受硬件支持的堆栈的顶部。具体来说,首先将ESP递减4,然后将其操作数放入地址(%esp)的32位位置的内容中。由于x86堆栈向下增长,因此ESP(堆栈指针)通过推入递减-即,堆栈从高地址增长到低地址。

     

pop-从堆栈弹出

     

pop指令将4字节数据元素从硬件支持的堆栈的顶部移到指定的操作数(即寄存器或存储器位置)中。它首先将位于内存位置(%esp)的4个字节移至指定的寄存器或内存位置,然后将ESP递增4。

查找更多详细信息:push / pop explanation