有人可以向我解释这段代码的堆栈吗?
英语这不是我的第一语言,所以如果我拼写错了一些单词对不起。 我在堆栈中遇到了一些麻烦,我将在这里放置的所有代码完美地工作。
例如,这个代码很容易,我理解它的堆栈。
.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 -------
但有了这个代码我有一些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
代码工作完美,但我有很多问题呢? 现在堆栈中的%ebx和ret在哪里?
代码asm transalted在c:
int f(int x){ return x + g(y,z); }
这是我制作的堆叠
STACK
-------- 8(%esp) --> x parameter of function f -------- 4(%esp) --> z parameter of function g -------- (%esp) --> y parameter of funcion g --------
所以现在的问题是现在这个栈上的%ebx和ret在哪里?
第一个代码将返回到旧的ebx
值(可能不是有效的地址),而不是原始返回地址,它在ret
之前缺少pop ebx
。
在call a
指令之前,在第二个调用ss:esp
地址的内存中包含:
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 ...
你的“esp + x”表示法不起作用,因为esp确实是动态变化的,所以如果你想像这样描述栈,你必须说明你正在使用的代码中哪个位置(esp的值)。 IE浏览器。 在的条目f
的mov eax,[esp+4]
将加载的“X”,但此后后来只是一个指令push ebx
同样的事情是由达到mov eax,[esp+8]
(Intel语法,转换为“机器”gas / at&t语法,我是人类)。
但即使如此,如果您将其视为内存值,它会随着每次push
或写入内存而动态变化,因此您仍然必须指定在哪个执行点描述堆栈(就像我在call a
之前做过的那样,因为此前call a
有指令的地址addl %ebx, %eax
书面提前该值的1
代码中的a
问题没有显示。
反正老ebx
和返回地址保存在内存中在同一个地方所有的时间(除非a
覆盖它们),它不是移动内容。 这是由push/pop/add/sub
进行调整的指针esp
。 (即使pop
它,内存内容仍会保留一段未定义的时间,但假设其他代码覆盖它多长时间是不安全的,如果SW中断处理程序正在使用应用程序堆栈,它可能会被覆盖虽然在x86 32b模式下,通常应用程序拥有自己的堆栈,因此这些值可能会停留在那里,直到您通过下一次push
或call
或其他方式覆盖它们)。
最后,编译这些东西,并在调试器中运行它们,在开始时将内存视图放到ss:esp-32
中,然后观察如何通过诸如call
或push
类的指令来写入内存,以及esp
如何更改为指向“堆栈顶部”。 在调试器中“观看”通常要比阅读我的答案更容易。
上一篇: can someone explain me the stack of this code?
下一篇: Need help in clarifying simply Assembly code and feedback about my analyzis