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.
上一篇: x86方式来告诉数据的指令
下一篇: 有人可以向我解释这段代码的堆栈吗?