【发布时间】:2013-11-02 09:16:09
【问题描述】:
我试图找出为什么在 windows 中对同一程序的指令比 linux 多得多。
所以我只是在 C 中使用了int a=0xbeef; 和printf("test\n");,并在 Linux 和 Windows 中编译。当我调试和拆卸主机时,我得到了这个:
在 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 的 2 倍……这让我思考。还有一件事:从 main+9 到 main+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
leave 然后 xor 然后 ret。好的 :D 调用 _alloca 和调用 __main 仍然存在。我不知道0x401291 <main+1>: mov $0x10,%eax 在这里做什么:D
【问题讨论】:
-
哇。似乎 Windows 上的编译器正在控制 ALU。
-
这只是样板 ABI 的东西,但是用 -O3 编译两者,它可能会缩小一点。
标签: c linux windows assembly gdb