用汇编语言访问栈帧

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时,堆栈看起来像这样。
            ESP is here
|     2    | Ebp + 12
|     5    | Ebp + 8
|     4    | Ebp + 4
|          | Old EBP value

文章错了还是我理解有误?
2个回答

6
使用ebp的原因是esp会发生变化,例如传递参数给子例程。因此,您的ebp将使您能够使用相同的偏移量访问相同的变量,无论esp在那一刻指向哪里。
当您将值推送到堆栈上时,它的值会减少;弹出时增加。
该代码减去12(4 * 3)以为3个32位(4字节)整数腾出空间。Ebp指向“底部”,即esp之前的位置。因此,您使用负偏移量访问变量,例如ebp-4。因此,您的图片是错误的:ebp+任何内容指向您的代码不应操作的某些内容。
     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。


所以可以肯定地说视频中提到的是错误的吗?我已经开始理解堆栈的概念,但是当我看视频时感到困惑。根据视频,要访问基指针以上的值或任何内容,应该将某些内容添加到 EBP。要访问基指针以下的任何内容,我们应该从 EBP 中减去一些内容。?? - srh snl
我现在看不到视频;假设“above”表示“递减地址”,答案很明显:要访问指针所指向的位置之前(即“above”)的内容,必须递减指针。反之亦然,必须递增它。(你的“to access anything from below...”中“from”的意义不清楚。) - ShinTakezou
没关系。此外,我阅读的所有文章(除了那个视频)都说我需要执行[EBP - whatever]来获取EBP上面的值。谢谢。现在很清楚了。 :D - srh snl

2
stack-pointer(基指针)地址“向下增长”,即在地址空间中向较低的地址方向。例如,您的堆栈从0x70000000开始,当您对其进行push操作时,esp (ebp)会降低一个双字节(dword)->0x6ffffffc(如果我理解正确)。请参见此处此处此处

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接