【发布时间】:2011-09-04 20:37:18
【问题描述】:
我不确定我做错了什么,但我尝试阅读有关 GCC 调用约定的手册,但没有发现任何有用的内容。我目前的问题是 GCC 为一个非常简单的操作生成了过多的代码,如下所示。
main.c:
#ifdef __GNUC__
// defines for GCC
typedef void (* push1)(unsigned long);
#define PUSH1(P,A0)((push1)P)((unsigned long)A0)
#else
// defines for MSC
typedef void (__stdcall * push1)(unsigned long);
#define PUSH1(P,A0)((push1)P)((unsigned long)A0)
#endif
int main() {
// pointer to nasm-linked exit syscall "function".
// will not work for win32 target, provided as an example.
PUSH1(0x08048200,0x7F);
}
现在,让我们使用 gcc 构建和转储它:gcc -c main.c -Os;objdump -d main.o:
main.o: file format elf32-i386
Disassembly of section .text:
00000000 <.text>:
0: 8d 4c 24 04 lea 0x4(%esp),%ecx
4: 83 e4 f0 and $0xfffffff0,%esp
7: ff 71 fc pushl -0x4(%ecx)
a: b8 00 82 04 08 mov $0x8048200,%eax
f: 55 push %ebp
10: 89 e5 mov %esp,%ebp
12: 51 push %ecx
13: 83 ec 10 sub $0x10,%esp
16: 6a 7f push $0x7f
18: ff d0 call *%eax
1a: 8b 4d fc mov -0x4(%ebp),%ecx
1d: 83 c4 0c add $0xc,%esp
20: c9 leave
21: 8d 61 fc lea -0x4(%ecx),%esp
24: c3 ret
这是我能得到的最小尺寸代码...如果我不指定 -O* 或指定其他值,它将是 0x29 + 字节长。
现在,让我们使用 ms c 编译器 v 6 构建它(是的,98 年 iirc 之一):wine /mnt/ssd/msc/6/cl /c /TC main.c;wine /mnt/ssd/msc/6/dumpbin /disasm main.obj:
Dump of file main.obj
File Type: COFF OBJECT
_main:
00000000: 55 push ebp
00000001: 8B EC mov ebp,esp
00000003: 6A 7F push 7Fh
00000005: B8 00 82 04 08 mov eax,8048200h
0000000A: FF D0 call eax
0000000C: 5D pop ebp
0000000D: C3 ret
如何让 GCC 生成类似大小的代码?任何提示,提示?您不同意生成的代码应该那么小吗?为什么 GCC 会附加这么多无用的代码?我认为在优化大小时它会比 msc6 之类的旧东西更聪明。我在这里错过了什么?
【问题讨论】:
-
使用
-O3而不是-Os会为我生成一个更小的文件。 -
对我来说它生成 0x28 vs 0x25 字节,你的版本是什么?
-
我什至不明白代码应该做什么;)
标签: c gcc assembly x86 compiler-optimization