3

我找到了这个汇编代码,在分析它时,我意识到我没有看到这里的堆栈清理或平衡。而且我认为访问堆栈就像dword ptr [ebp-8]弹出内容一样。我是否正确,如果不是,那么为什么下面的代码没有显示任何pop指令或add esp, whatever

_AddMe:
push ebp
mov ebp, esp
sub esp, 0ch
mov eax, dword ptr [ebp+0ch]
mov dword ptr [ebp-4], eax
mov eax, dword ptr [ebp+8]
mov dword ptr [ebp-8], eax
mov eax, dword ptr [ebp-8]
add eax, dword ptr [ebp-4]
mov dword ptr [ebp-0ch], eax
mov eax, dword ptr [ebp-0ch]
jmp AddMeEpilogue
AddMeEpilogue:
mov esp, ebp
pop ebp
ret
4

2 回答 2

7

您可以手动递增和递减堆栈指针,因此对 esp 进行加减运算与 push 和 pop 操作基本相似。

例子

mov eax, 2134
push eax
mov ebx, [esp]
add esp, 04    <-- This is the actual pop operation.
mov ecx, [esp-4]
ret

可以看到我在push之后没有做pop,但是代码仍然执行正确,类似。

push eax
pop ebx
mov ecx, ebx

访问堆栈不会改变它的正确性。因此,如果您执行 amov eax, dword ptr [ebp-0ch]并不意味着堆栈是正确的或不正确的,因为它只是从恰好是堆栈的内存中获取一些值。只有增加或减少 ESP 才有意义,可以认为是push操作pop

于 2013-05-22T10:25:37.730 回答
4

EBP在进入函数时保存在堆栈中,然后设置为指向当前堆栈的顶部(mov ebp,esp)。

然后通过向下移动堆栈指针 ( sub esp,0ch) 在堆栈上分配一些局部变量空间。然后使用EBP 减去偏移量(因为在减法之前EBP等于)来引用该区域中的数据。ESP

同时使用EBP 偏移量访问函数参数。

在函数返回之前,它恢复ESPEBP(mov esp,ebp设置ESPpush ebp函数开头之后的值)。

于 2013-05-22T10:36:59.773 回答