我试图理解以下函数的解压缩代码。
void func(char *string) {
printf("the string is %s\n",string);
}解压缩代码如下所示。
1) 0x080483e4 <+0>: push %ebp
2) 0x080483e5 <+1>: mov %esp,%ebp
3) 0x080483e7 <+3>: sub $0x18,%esp
4) 0x080483ea <+6>: mov $0x80484f0,%eax
5) 0x080483ef <+11>: mov 0x8(%ebp),%edx
6) 0x080483f2 <+14>: mov %edx,0x4(%esp)
7) 0x080483f6 <+18>: mov %eax,(%esp)
8) 0x080483f9 <+21>: call 0x8048300 <printf@plt>有人能告诉我第4-7行是什么意思(不是字面解释)吗?另外,为什么在第3行的堆栈上分配24个字节?
发布于 2013-08-25 11:23:58
基本上,这里发生的事情:
4) 0x080483ea <+6> : mov $0x80484f0,%eax将"the string is %s\n"地址加载到eax中。
5) 0x080483ef <+11>: mov 0x8(%ebp),%edx将参数string移到edx中。
6) 0x080483f2 <+14>: mov %edx,0x4(%esp)将edx或string的值推入堆栈,printf的第二个参数
7) 0x080483f6 <+18>: mov %eax,(%esp)将eax或"the string is %s\n"的值推入堆栈,首先是printf的参数,然后调用printf。
sub $0x18,%esp是不必要的,因为函数没有局部变量,gcc似乎喜欢留出额外的空间,但老实说,我不知道为什么。
发布于 2013-08-25 11:43:55
堆栈是一个连续的内存区域,从较高的地址开始,以esp结束。每当需要增加堆栈时,都可以从esp中减去。每个函数都可以在堆栈上有一个框架。它是该函数拥有的堆栈的一部分,并负责完成后的清理。这意味着,当函数启动时,它会减少esp以创建其框架。当它结束时,它会增加它回来。ebp通常指向帧的开头。
最初,该函数将ebp推到tha堆栈,以便在函数结束时存储它,设置esp = ebp标记其帧的开始,并分配28个字节。为什么是28?为了对齐。它已经为ebp分配了4个字节。4+ 28 = 32
第4-7行将准备对printf的调用。它希望它的参数在调用者的框架上。当我们阅读mov 0x8(%ebp), %edx时,我们从调用者的框架中获取我们的论点char* string。printf也会这么做。
注意,您的程序集缺少一个leave和一个ret指令来清除堆栈并返回给调用方。
https://stackoverflow.com/questions/18428243
复制相似问题