4

我是组装新手,然后我遇到了这篇文章

它说这段代码

void MyFunction()
{
  int a, b, c;
  a = 10;
  b = 5;
  c = 2;

相当于这个

push ebp     ; save the value of ebp
mov ebp, esp ; ebp now points to the top of the stack
sub esp, 12  ; space allocated on the stack for the local variables
mov [ebp -  4], 10  ; location of variable a
mov [ebp -  8], 5   ; location of b
mov [ebp - 12], 2   ; location of c

根据这个视频,要访问基指针上方的堆栈值,我们应该添加。如果它低于指针,我们应该减去。鉴于上面的例子,他们从基指针中减去了一些东西来移动所需变量的位置,这与视频中的说明相反。

我错过了什么?我知道 sub esp, 12 正在为局部变量分配空间,所以我想到的是 EBP 低于该分配,所以我认为它应该是 [ebp + something] 而不是减去。

所以当他做这个 sub esp, 12 时,这就是 Stack 的样子。

            ESP is here
|     2    | Ebp + 12
|     5    | Ebp + 8
|     4    | Ebp + 4
|          | Old EBP value

文章是错的,还是我误解了?

4

2 回答 2

6

使用 ebp 的原因是 esp 会发生变化,例如将参数传递给子程序。因此,您的 ebp 将使您能够使用相同的偏移量访问相同的变量,无论 esp 在那一刻指向何处。

当您将值压入堆栈时,其值会递减;弹出时增加。

代码减去 12 (4*3) 为 3 个 32 位(4 字节)整数腾出空间。Ebp 指向“底部”, esp 之前所在的位置。因此,您可以使用负偏移量访问变量,例如 ebp-4。所以你的图片是错误的:ebp+Whatever 指向你的代码不应该使用的东西。

     BEFORE

     lower address
     |
     |<--------------  esp (=ebp after mov ebp, esp)
     |
     | 
     higher address


     AFTER mov ebp, esp; sub esp, 12

     lower address
     |<--------------  esp
     |
     |
     |<--------------  ebp
     |
     | 
     higher address


     AFTER mov [ebp-4], 10 ecc.

     lower address
     | 2  <--------------  esp
     | 5
     | 10
     |<--------------  ebp
     |
     | 
     higher address

此时[esp]将检索 [ebp-12] 即 2。

于 2013-05-22T08:48:53.027 回答
2

stack-pointer基指针)地址向下“增长”,朝向地址空间中的较低地址。
例如,您的堆栈从开始,0x70000000当您push在其上放置某些东西时,esp (ebp)将降低 dword -> 0x6ffffffc(如果我是正确的)。

这里这里这里

于 2013-05-22T08:32:55.853 回答