繁体   English   中英

拆卸C函数

[英]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)

edxstring的值压入堆栈,即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将执行相同的操作。

请注意,您的组件缺少leaveret指令清除栈,并返回给调用者。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM