【发布时间】:2011-01-10 19:35:34
【问题描述】:
为了了解底层发生的事情,我正在编写小型 C 程序,然后将其反转,并尝试了解其 objdump 输出。
C 程序是:
#include <stdio.h>
int function(int a, int b, int c) {
printf("%d, %d, %d\n", a,b,c);
}
int main() {
int a;
int *ptr;
asm("nop");
function(1,2,3);
}
函数的 objdump 输出给了我以下信息。
080483a4 <function>:
80483a4: 55 push ebp
80483a5: 89 e5 mov ebp,esp
80483a7: 83 ec 08 sub esp,0x8
80483aa: ff 75 10 push DWORD PTR [ebp+16]
80483ad: ff 75 0c push DWORD PTR [ebp+12]
80483b0: ff 75 08 push DWORD PTR [ebp+8]
80483b3: 68 04 85 04 08 push 0x8048504
80483b8: e8 fb fe ff ff call 80482b8 <printf@plt>
80483bd: 83 c4 10 add esp,0x10
80483c0: c9 leave
请注意,在调用 printf 之前,三个偏移量为 8、16、12 的 DWORD(它们必须是 function 的参数以相反的顺序)被压入堆栈。稍后将推送一个十六进制地址,该地址必须是格式字符串的地址。
My doubt is
- 与其直接将 3 个 DWORDS 和格式说明符压入堆栈,我希望看到 esp 被手动递减,然后值被压入堆栈。如何解释这种行为?
【问题讨论】:
-
objdump 的
-l开关(这是一个小写的 L)可能会对您有所帮助;如果没有这个,那么在未来。 -
推送会修改 esp。为什么你期望它也应该明确地完成?
-
是的,来自
push的描述:“递减堆栈指针,然后将源操作数存储在堆栈顶部”。 -
这个汇编没有意义。为什么编译器会从内存中推送文字常量而不是生成立即数?那个 C 代码是真正的源代码吗?
-
是的,那是真正的源代码。而且编译一直没有优化,可能是这个原因吧?
标签: c gcc assembly disassembly