使用汇编语言访问堆栈帧

srh*_*snl 4 assembly masm stack-frame

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

它说这个代码

void MyFunction()
{
  int a, b, c;
  a = 10;
  b = 5;
  c = 2;
Run Code Online (Sandbox Code Playgroud)

相当于此

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
Run Code Online (Sandbox Code Playgroud)

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

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

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

            ESP is here
|     2    | Ebp + 12
|     5    | Ebp + 8
|     4    | Ebp + 4
|          | Old EBP value
Run Code Online (Sandbox Code Playgroud)

这篇文章错了,还是我错了?

Shi*_*zou 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
Run Code Online (Sandbox Code Playgroud)

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