内存堆栈:来自 esp 的 sub 20

memory stack: sub 20 from esp

我无法理解这个 Whosebug 线程中的答案。

在答案的中间写着 Most function prologs look something like:...

据我了解上述答案中的说明 --> 第一条指令将 ebp 压入堆栈。然后我们将 esp 移动到 ebp。最后我们从 esp 中减去 20,使 esp 点从原来的位置向下指向 20 个地址。

根据上面的说明,我将堆栈想象成这样。

high address
__________________________
|     (an address)       |    <-- ebp
..........................
..........................
|                        |    <-- esp points to an address 20 
|                        |        bytes lower
|                        |
|                        |
|                        |
|________________________|
low address

如果这个可视化是正确的,那么当你甚至没有任何关于下一个局部变量可以放置的位置的引用时,你怎么能将任何东西压入堆栈?

'low address' 是堆栈指针 ESP 所在的位置。将任何内容推入堆栈都会将其存储在该地址下方。

存储局部变量将使用 EBP 具有负偏移量的相对寻址模式

在您的示例中,EBPESP 之间存在 20 个字节的差异。
在没有任何推送的情况下,MOVing 到 ESPpoints 填充该 20 字节区域的最低 4 字节。相反,第一个 PUSH 将存储在该 20 字节区域下方。只有 PUSH 指令会预先降低堆栈指针。 MOV 按原样使用 ESP

以下存储到内存中的相同地址:

mov [ebp-20], eax
mov [esp], eax

现在,如果我们 push 将一些新数据添加到堆栈,那么 ESP 会发生变化,但 EBP 仍然存在,因此以下内容为真:

push ebx              <<< The first push
mov  eax, [ebp-20]    <<< Still at -20
mov  edx, [esp+4]     <<< Now at +4

EAXEDX彼此相等。