c - GCC 4.3/4.4 与 MSC 6 在 i386 上的大小优化失败

标签 c gcc assembly x86 compiler-optimization

我不确定我做错了什么,但我已经尝试阅读有关 GCC 调用约定的手册,但没有发现任何有用的东西。我当前的问题是 GCC 为非常简单的操作生成了过大的代码,如下所示。

主.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 这样的旧东西更聪明。我在这里缺少什么?

最佳答案

main() 在这里很特别:gcc 正在做一些额外的工作,使堆栈在程序的入口点对齐 16 字节。所以结果的大小不能直接比较...尝试将 main() 重命名为 f(),您会看到 gcc 生成截然不同的代码。

(MSVC 编译的代码不需要关心对齐,因为 Windows 有不同的堆栈对齐规则。)

关于c - GCC 4.3/4.4 与 MSC 6 在 i386 上的大小优化失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7301969/

相关文章:

c - 什么时候指向同一个对象的指针相等?

c++ - 在代码块中运行发布版本时出现段错误,但运行调试版本时不会出现段错误

c - GetPhysicallyInstalledMemory 函数 - C 中 undefined reference

在 gcc 9.3 中编译但不能在 gcc 10.2 中编译的 C++ 代码

gcc - Nao 机器人上的 gentoo 版本出现问题

linux - 如何不在 NASM 中发出局部符号,以便 GDB disas 不会停在它们上面?

assembly - M68000 基本问题,Neo Geo - 相关

assembly - TBYTE 可容纳的最大值(value)

Concatenating Strings-changing words into pig latin 拼接字符串

c - 请解释一下这个比较字符串的方法