【发布时间】:2017-03-02 19:41:12
【问题描述】:
我了解汇编和 c 编程的基础知识。
我用 C 编译了以下简单程序,
#include <stdio.h>
int main()
{
int a;
int b;
a = 10;
b = 88
return 0;
}
使用以下命令编译,
gcc -ggdb -fno-stack-protector test.c -o test
上述程序gcc 4.4.7版本的反汇编代码为:
5 push %ebp
89 e5 mov %esp,%ebp
83 ec 10 sub $0x10,%esp
c7 45 f8 0a 00 00 00 movl $0xa,-0x8(%ebp)
c7 45 fc 58 00 00 00 movl $0x58,-0x4(%ebp)
b8 00 00 00 00 mov $0x0,%eax
c9 leave
c3 ret
90 nop
但是,使用 gcc 版本 4.3.3 的同一程序的反汇编代码是:
8d 4c 23 04 lea 0x4(%esp), %ecx
83 e4 f0 and $0xfffffff0, %esp
55 push -0x4(%ecx)
89 e5 mov %esp,%ebp
51 push %ecx
83 ec 10 sub $0x10,%esp
c7 45 f4 0a 00 00 00 00 movl $0xa, -0xc(%ebp)
c7 45 f8 58 00 00 00 00 movl $0x58, -0x8(%ebp)
b8 00 00 00 00 mov $0x0, %eax
83 c4 10 add $0x10,%esp
59 pop %ecx
5d pop %ebp
8d 61 fc lea -0x4(%ecx),%esp
c3 ret
为什么汇编代码有差异?
正如您在第二个汇编代码中所见,为什么将 %ecx 推入堆栈?and $0xfffffff0, %esp有什么意义?
注意:操作系统相同
【问题讨论】:
-
为什么不应该有区别?
-
编译器会随着时间而改变和改进。所以你希望 4.4.7 生成比 4.3.3 更好的代码。
-
@ForceBru ups...“程序集应该是从 C 语言到机器语言的直接翻译”——绝对不是,对编译器的任何要求都比不上它。如果你想要直接指令 -> 机器码翻译,你应该使用汇编。
-
@jforberg:我们甚至不知道操作系统和 gcc 的默认优化设置(不,命令行不够)。 OP 没有研究 C 翻译器必须做什么(即抽象机器等)。已经有很多材料可以通过简单的搜索找到。
-
@ForceBru 很好,他们在 C 中做同样的事情,但是 C 没有直接翻译成机器代码,有几十到几百种如何翻译 C 源代码的合理方法,数百万不合理的方法。即使您使用
-O3告诉编译器“我想要最快的代码”,这也是 NP 完全问题,编译器无法解决,并且输出只是启发式地接近最优解。您逻辑中的主要问题是“您只能以一种方式有效地做到这一点”-您不能。即使是中型任务的汇编程序员也会产生不同的代码,有太多 [***llions] 方法。