【发布时间】:2011-06-12 16:44:28
【问题描述】:
嘿嘿,
我编写了这个非常基本的 main 函数来试验反汇编,并希望了解底层发生了什么:
int main() {
return 6;
}
使用 gdb 来 disas main 会产生这样的结果:
0x08048374 <main+0>: lea 0x4(%esp),%ecx
0x08048378 <main+4>: and $0xfffffff0,%esp
0x0804837b <main+7>: pushl -0x4(%ecx)
0x0804837e <main+10>: push %ebp
0x0804837f <main+11>: mov %esp,%ebp
0x08048381 <main+13>: push %ecx
0x08048382 <main+14>: mov $0x6,%eax
0x08048387 <main+19>: pop %ecx
0x08048388 <main+20>: pop %ebp
0x08048389 <main+21>: lea -0x4(%ecx),%esp
0x0804838c <main+24>: ret
这是我对正在发生的事情以及我需要逐行帮助的最佳猜测:
lea 0x4(%esp),%ecx
将esp + 4的地址加载到ecx中。 为什么要在 esp 上加 4?
我在某处读到这是命令行参数的地址。但是当我做x/d $ecx 时,我得到了 argc 的值。 实际的命令行参数值存储在哪里?
and $0xfffffff0,%esp
对齐堆栈
pushl -0x4(%ecx)
将 esp 最初所在的地址压入堆栈。 这样做的目的是什么?
push %ebp
将基指针压入堆栈
mov %esp,%ebp
将当前堆栈指针移动到基指针中
push %ecx
将原始 esp + 4 的地址压入堆栈。 为什么?
mov $0x6,%eax
我想在这里返回 6 所以我猜返回值存储在 eax 中?
pop %ecx
将 ecx 恢复为堆栈上的值。 当我们返回时,为什么我们希望 ecx 为 esp + 4?
pop %ebp
将 ebp 恢复为堆栈上的值
lea -0x4(%ecx),%esp
将esp恢复到原来的值
ret
在组装方面我是一个 n00b,所以任何帮助都会很棒!另外,如果您看到任何关于我认为发生的错误的陈述,请纠正我。
非常感谢! :]
【问题讨论】:
-
投票结束过于广泛。请关注每个问题您不确定的一点。
-
我不认为这篇文章太宽泛了。是的,它确实有多个问题,但关注的“单点”是理解基本的拆卸。你的提议是我单独提出每个问题。这对我来说没有意义,因为每个问题都没有上下文。我不会向每个关于一条装配线的问题发送一些垃圾邮件。另外,这篇文章已有 4 年历史了。
-
别担心,太宽泛是很主观的,我们可能都是对的 :-) 干杯。
-
对于一个有这么多有效和有趣答案的问题,我真的不认为结束是完全正确的。
标签: linux assembly gdb x86 disassembly