![](/img/trans.png)
[英]How to copy a function from disassembly to Visual Studio and be able to call it from C level?
[英]Disassembly of a C function
我试图理解以下功能的反汇编代码。
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个字节?
基本上这里会发生什么:
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似乎想腾出更多空间,但是老实说我不知道为什么。
堆栈是内存的连续区域,从较高的地址开始,到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
指令清除栈,并返回给调用者。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.