can someone explain me the stack of this code?

English it's not my first language so if i spell wrong some words sorry. I've some trouble with the stack, all codes that i will put here works perfectly.

This code for example it's easy and i understand the stack of it.


    .globl f 
    f:

    push %ebx
    movl 8(%esp), %eax
    movl 12(%esp), %ebx

    addl %ebx, %eax

    ret

STACK

    -------
    VAR Y --> ESP + 12
    -------
    VAR X --> ESP + 8
    -------
    RET   --> RETURN
    -------
    %EBX  --> %ESP
    -------

But with this code i've some t


    .code32

    .globl f

    f:

        pushl %ebx

        movl 8(%esp), %ebx

        subl $8, %esp # Creo posto nella stack per i parametri

        movl $1, (%esp)

        movl $2, 4(%esp)

        call a

        addl %ebx, %eax

        addl $8, %esp #Tolgo posto nella stack

        popl %ebx

        ret


The code work perfectly but i've many question about that?. Where is %ebx and ret on stack now?

Code of asm transalted in c:


    int f(int x){

    return x + g(y,z);

    }

And this is the stack that i've made

STACK


    --------
    8(%esp) --> x parameter of function f
    --------
    4(%esp) --> z parameter of function g
    --------
    (%esp)  -->  y parameter of funcion g
    --------

So the question now is where are %ebx and ret on this stack now?


The first code will return to old ebx value (probably not a valid address), not to the original return address, it's missing pop ebx ahead of ret .

In the second call the memory at ss:esp address, before call a instruction, contains:

dword 1                     +0 (current esp)
dword 2                     +4
dword old_ebx_value         +8
dword return_address_from_f +12
dword x                     +16
... older stack content ...

Your "esp+x" notation doesn't work, as the esp does change dynamically, so if you want to describe stack like that, you have to say at which position in the code (which value of esp) you are using. Ie. at the entry of f the mov eax,[esp+4] will load the "x", but just one instruction later after push ebx the same thing is achieved by mov eax,[esp+8] (Intel syntax, convert to that "machine" gas/at&t syntax by yourself, I'm human).

But even then, if you will picture it as memory values, it is dynamically changing with every push or write to memory, so you still have to specify at which point of execution you are describing the stack (like I did ahead of call a , because after call a there's the address of instruction addl %ebx, %eax written ahead of that value 1 and code at a is not shown in question.

Anyway the old ebx and return address are in the memory at the same place all the time (unless a overwrites them), it's not the content that moves. It's the pointer esp that is being adjusted by push/pop/add/sub . (the memory content will stay for some undefined period of time even after you pop it, it's just not safe to assume how long it takes other code to overwrite it, in case the SW interrupt handlers are using the app stack it may be overwritten any time, although in x86 32b mode usually the app has it's own stack, so then those values will probably stay there until you overwrite them by next push or call or some other way).

Finally, just make those things to compile, and run them in debugger, put memory view to ss:esp-32 at the beginning, and watch how the memory is being written to by instructions like call or push , and how esp does change to point to the "top of stack". It's usually much easier to "watch it" in debugger, than reading text like my answer.

链接地址: http://www.djcxy.com/p/80348.html

上一篇: x86方式来告诉数据的指令

下一篇: 有人可以向我解释这段代码的堆栈吗?