在Windows上生成垃圾的gcc? windows vs linux

我试图找出为什么在Windows有相同的程序比Linux更多的指示。 所以我只是用int a=0xbeef;printf("test\n"); 在C和编译在Linux和Windows。 当我debugging和反汇编主框架我得到这个:在Linux上:

 0x080483e4 <+0>: push %ebp 0x080483e5 <+1>: mov %esp,%ebp 0x080483e7 <+3>: and $0xfffffff0,%esp 0x080483ea <+6>: sub $0x20,%esp 0x080483ed <+9>: movl $0xbeef,0x1c(%esp) 0x080483f5 <+17>: movl $0x80484d0,(%esp) 0x080483fc <+24>: call 0x8048318 <puts@plt> 0x08048401 <+29>: leave 0x08048402 <+30>: ret 

好的,这很好。 我看到esp的movl 0x1c偏移量将值放在那里。

但在Windows中,我得到了这个:

 0x401290 <main>: push %ebp 0x401291 <main+1>: mov %esp,%ebp 0x401293 <main+3>: sub $0x18,%esp 0x401296 <main+6>: and $0xfffffff0,%esp 0x401299 <main+9>: mov $0x0,%eax 0x40129e <main+14>: add $0xf,%eax 0x4012a1 <main+17>: add $0xf,%eax 0x4012a4 <main+20>: shr $0x4,%eax 0x4012a7 <main+23>: shl $0x4,%eax 0x4012aa <main+26>: mov %eax,0xfffffff8(%ebp) 0x4012ad <main+29>: mov 0xfffffff8(%ebp),%eax 0x4012b0 <main+32>: call 0x401720 <_alloca> 0x4012b5 <main+37>: call 0x4013c0 <__main> 0x4012ba <main+42>: movl $0xbeef,0xfffffffc(%ebp) 0x4012c1 <main+49>: movl $0x403000,(%esp,1) 0x4012c8 <main+56>: call 0x401810 <printf> 0x4012cd <main+61>: mov $0x0,%eax 0x4012d2 <main+66>: leave 0x4012d3 <main+67>: ret 

首先,我不知道为什么Windows编译器(mingw)生成这么多的代码。 比Linux多两倍……这让我思考。 还有一件事:从主+ 9到主+ 37我看不到这个代码的重点。

我会感谢如果有人回答这个,我只是好奇:)

编辑:与Linux上的-O3参数我得到了相同的,在Windows中像魔术发生:

 0x401290 <main>: push %ebp 0x401291 <main+1>: mov $0x10,%eax 0x401296 <main+6>: mov %esp,%ebp 0x401298 <main+8>: sub $0x8,%esp 0x40129b <main+11>: and $0xfffffff0,%esp 0x40129e <main+14>: call 0x401700 <_alloca> 0x4012a3 <main+19>: call 0x4013a0 <__main> 0x4012a8 <main+24>: movl $0x403000,(%esp,1) 0x4012af <main+31>: call 0x4017f0 <puts> 0x4012b4 <main+36>: leave 0x4012b5 <main+37>: xor %eax,%eax 0x4012b7 <main+39>: ret 

然后离开然后ret。 好的:D调用_alloca并调用__main仍然在那里。 我不知道什么是0x401291 <main+1>: mov $0x10,%eax在这里做:D

Solutions Collecting From Web of "在Windows上生成垃圾的gcc? windows vs linux"

你似乎正在用旧的3.x系列gcc ,你最好升级。 较新的版本不会调用alloca 。 我怀疑特定的版本的alloca可能会使用注册约定,所以mov 0x10,%eax可能设置该调用的参数。

__maincrtbegin.o中定义的一个启动函数,它执行全局构造函数,并使用将运行全局析构函数的atexit注册一个函数。

还要注意, main得到了特殊的处理,如栈对齐码和上面提到的初始化。 如果您只是对代码生成问题感兴趣,那么反而比较一个“简单”函数可能是一个好主意。

一个注意到,在上面的例子中编译器正在调用puts,而在下面的是printf。 我会怀疑你已经在顶部的例子优化,但不是在较低的例子。

它也可能是一个调试与非调试版本。