尤指使用函数参数堆栈EBP和行为 [英] Behaviour of ebp and esp in stacks using function with parameter

查看:238
本文介绍了尤指使用函数参数堆栈EBP和行为的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想更多地了解堆栈。尤其是,当带参数的函数调用会发生什么。对于这一点,我写了下面的code:

i want to learn more about stack. Especially, what happens when a function with parameter are called. For this, i write the following code:

    #include <stdio.h>
    int sum(int d, int e, int f){
        int result = d + e + f;
        return result;
    }

   int main(void){
   int a = 5;
   int b = 4;
   int c = 2;

   int erg = sum(a,b,c);
   printf("Result is: %d", erg);

   }

和我得到以下总成 - code(我只会添加功能的一部分,因为首先我想了解这部分):

and I get the following Assembly-Code(I will only add the part of the main function, because first I want to understand this section):

    push ebp,
    mov ebp, esp
    and esp, -16
    sub esp, 32
    mov DWORD PTR[esp+28], 5
    mov DWORD PTR[esp+24], 4
    mov DWORD PTR[esp+20], 2
    mov eax, DWORD PTR[esp+20]
    mov DWORD PTR[esp+8], eax
    mov eax, DWORD PTR[esp+24]
    mov DWORTD PTR[esp+4], eax
    mov eax, DWORD PTR[esp+28]
    mov DWORD PTR[esp], eax
    call sum
    ........
    ........

所以,对于这一部分,我画一个草图一点为自己。请看一下 :)
我的问题:哪里是在这一点上我的 EBP ?因为我的汇编code的2线,它必须是在像同一个地方[ESP] ,对不对?

So, for this part I draw a little sketch to for myself. Please take a look :) My question : Where is at that point my ebp? Because of line 2 of my assembler code, it must be at the same place like [esp], right ?

现在,和函数的一部分,随后我的第二个问题。

Now, the part of sum function which follows to my second question.

所以这里是该总成 - code:

so here is the assembly-code of that:

    push ebp
    mov ebp, esp
    sub esp, 16
    mov eax, DWORD PTR[ebp+12]
    mov edx, DWORD PTR[ebp+8]
    mov edx, eax
    ------------

所以,我已经了解到,我们可以找到我们的参数总是 [EB + 12] [EBP + 8]
(我跳过了第三个参数,因为我想保持简单)
所以我的问题是现在:
如果我假设尤其 = EBP ,我看我的草图,然后我看到有没有在 [ESP + 12] 或现在 [EBP + 12] 。但尽管如此,它被使用。
我怎么能想象吗?

so, I had learned that we can find our parameters always in [eb+12] and [ebp+8]. (I skipped the third parameter because I want to keep it simple) So my question is now: If I assume that esp=ebp and I look at my sketch, then I see that there is nothing in [esp+12] or now [ebp+12]. But nevertheless, it is used. How can I imagine that?

有人能帮助我吗?我读过那么多的论文,但似乎没有人绘制这些事情。正因为如此,它是很难体会到的。

Can someone help me? I've read so many papers, but nobody seems to sketch these things. Because of that, it is very hard to understand that.

感谢您!

下面是我的草图:

推荐答案

在第一个函数执行尤其 EBP 指令 MOV EBP,ESP 后才立刻拥有相同的值。之后,和ESP,-16 归零尤其的低4位(最低的四位)和尤其 EBP 发散,除非尤其是零已经。然后子ESP,32 减去32从尤其这里尤其 EBP 分歧是肯定的。

During the first function execution esp and ebp have the same value only immediately after the instruction mov ebp, esp. After that and esp, -16 zeroes the lowest 4 bits (the lowest nibble) of esp, and esp and ebp diverge, unless the lowest bits of esp were zeroes already. Then sub esp, 32 subtracts 32 from esp and here esp and ebp diverge for sure.

push ebp                   ; esp = esp - 4; [esp] = ebp.
mov ebp, esp               ; ebp = esp. create the stack frame. 
and esp, -16               ; make lowest 4 bits of esp zeros, for alignment.
sub esp, 32                ; esp = esp - 32. make space for local variables.
mov DWORD PTR[esp+28], 5   ; a = 5
mov DWORD PTR[esp+24], 4   ; b = 4
mov DWORD PTR[esp+20], 2   ; c = 2
mov eax, DWORD PTR[esp+20] ; eax = c (eax = 2)
mov DWORD PTR[esp+8], eax  ; [esp+8] = dword 2
mov eax, DWORD PTR[esp+24] ; eax = b (eax = 4)
mov DWORTD PTR[esp+4], eax ; [esp+4] = dword 4
mov eax, DWORD PTR[esp+28] ; eax = a (eax = 5)
mov DWORD PTR[esp], eax    ; [esp] = dword 5
call sum                   ; the above lines define the parameters for the
                           ; function sum, that is called now.

那么关于你的第二个问题:

Then regarding your second question:

push ebp                   ; esp = esp - 4; [esp] = ebp.
mov ebp, esp               ; ebp = esp.
sub esp, 16                ; esp = esp - 16. create space for local variables.
                           ; at this point:
                           ; [ebp]    == old value of ebp.
                           ; [ebp+4]  == return address pushed by call,
                           ;             to be used by the next ret.
                           ; [ebp+8]  == dword 5 (a)
                           ; [ebp+12] == dword 4 (b)
                           ; [ebp+16] == dword 2 (c)
mov eax, DWORD PTR[ebp+12] ; eax = 4
mov edx, DWORD PTR[ebp+8]  ; edx = 5. gets overwritten by the next instruction.          
mov edx, eax               ; edx = eax = 4

不要以为尤其 == EBP 。在这第二个功能太尤其 EBP 分歧在指令的执行子ESP,16 。了解通过code使用调试器,例如GDB和单步执行,并按照寄存器(尤其是尤其)的值和内存的每个指令之后。您也可以调试code在你的脑袋像我上面做了,但是如果你是用汇编初学者,使用调试器通常是一个极大的方便,少了很多容易出错。

Don't assume esp == ebp. In this second function too esp and ebp diverge upon execution of the instruction sub esp,16. Learn to use a debugger, for example GDB and single-step through the code and follow the values of registers (especially esp) and memory after each instruction. You can also debug the code in your head as I did above, but if you are a beginner in assembly, using a debugger is usually a lot easier and a lot less error-prone.

这篇关于尤指使用函数参数堆栈EBP和行为的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆