Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/67.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
GCC 4.3/4.4与MSC 6在i386上针对大小失败的优化_C_Gcc_Assembly_X86_Compiler Optimization - Fatal编程技术网

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

GCC 4.3/4.4与MSC 6在i386上针对大小失败的优化,c,gcc,assembly,x86,compiler-optimization,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

我不确定我做错了什么,但我试着阅读了关于调用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-cmain.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
如何让GCC生成类似的大小代码?有什么提示吗?难道你不同意结果代码应该如此小吗?为什么GCC附加了这么多无用的代码?我认为在优化尺寸时,它比msc6这样的老东西更聪明。我在这里遗漏了什么?

是我能得到的最好的参考资料。我现在在Windows上,懒得登录Linux进行测试。在这里(MingWGCC4.5.2),代码比您的小。一个不同之处是调用约定,stdcall当然比cdecl(如果未指定,则默认为GCC,或者使用-O1,我猜也使用-Os)有几个字节的优势来清理堆栈

以下是我编译的方式和结果(源代码完全是从您的帖子中复制粘贴的)

gcc-S测试c:

_main:
    pushl   %ebp     #
    movl    %esp, %ebp   #,
    andl    $-16, %esp   #,
    subl    $16, %esp    #,
    call    ___main  #
    movl    $127, (%esp)     #,
    movl    $134513152, %eax     #, tmp59
    call    *%eax    # tmp59
    leave
    ret
gcc-c-o test.o test.c和&objdump-d test.o:

test.o:     file format pe-i386


Disassembly of section .text:

00000000 <_main>:
   0:   55                      push   %ebp
   1:   89 e5                   mov    %esp,%ebp
   3:   83 e4 f0                and    $0xfffffff0,%esp
   6:   83 ec 10                sub    $0x10,%esp
   9:   e8 00 00 00 00          call   e <_main+0xe>
   e:   c7 04 24 7f 00 00 00    movl   $0x7f,(%esp)
  15:   b8 00 82 04 08          mov    $0x8048200,%eax
  1a:   ff d0                   call   *%eax
  1c:   c9                      leave
  1d:   c3                      ret
  1e:   90                      nop
  1f:   90                      nop
test.o:文件格式pe-i386
第节的分解。正文:
00000000 :
0:55推力%ebp
1:89 e5 mov%esp,%ebp
3:83 e4 f0和$0xfffffff0,%esp
6:83 ec 10子$0x10,%esp
9:e8 00呼叫e
e:c7 04 24 7f 00 00动产$0x7f,(%esp)
15:b8 00 82 04 08 mov$0x8048200,%eax
1a:ff d0呼叫*%eax
1c:c9离开
1d:c3 ret
1e:90无
1f:90无
main()在这里很特别:gcc正在做一些额外的工作,使堆栈16字节在程序的入口点对齐。所以结果的大小不能直接比较。。。尝试将main()重命名为f(),您将看到gcc生成完全不同的代码


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

使用
-O3
而不是
-Os
为我生成一个较小的文件。对我来说,它生成0x28和0x25字节,你的版本是什么?我甚至不知道代码应该做什么;)抱歉,我没有注意到链接文档或任何其他提示中提到“大小”和“optim”字样。这描述了LinuxELF和glibc方面,这应该如何与我的问题联系起来,我不想把它联系起来,只想编译和组装。你到底是如何编译它的?你得到了多大的尺寸?连接在于对象格式,在这个平台上可能需要一些启动的东西。我将用生成的asm更新我的答案。太糟糕了。。。我不能得到相同的代码。尽管如此,如果你的cc的目标是pe-i386并不重要,代码仍然可能更小,移动到[esp]的方式看起来令人毛骨悚然,它应该是两字节的操作码“push 0x7F”。。。我还是不明白我该如何优化它。-Nostlib不是真的相关。。。试着重新理解。我相信其他的差异也可以归结为一致性;您可以使用-mprefered stack boundary=2覆盖它。
test.o:     file format pe-i386


Disassembly of section .text:

00000000 <_main>:
   0:   55                      push   %ebp
   1:   89 e5                   mov    %esp,%ebp
   3:   83 e4 f0                and    $0xfffffff0,%esp
   6:   83 ec 10                sub    $0x10,%esp
   9:   e8 00 00 00 00          call   e <_main+0xe>
   e:   c7 04 24 7f 00 00 00    movl   $0x7f,(%esp)
  15:   b8 00 82 04 08          mov    $0x8048200,%eax
  1a:   ff d0                   call   *%eax
  1c:   c9                      leave
  1d:   c3                      ret
  1e:   90                      nop
  1f:   90                      nop