2013-10-23 49 views
1

我想知道爲什麼在windows有相同的程序比linux更多的指令。 所以我剛剛在C中使用了int a=0xbeef;printf("test\n");,並在Linux和Windows中編譯。當我調試,拆卸主框架,我得到這個: 在Linux上:gcc在windows上產生垃圾? windows vs 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 <[email protected]> 
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我看不到該代碼的重點。

,如果有人回答這個我要感謝,我只是好奇:)

編輯: 隨着-O3在Linux上的說法我得到了相同的和Windows類似魔法happends:

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

+2

哇。看起來像Windows上的編譯器正在拖曳ALU。 – 2013-10-23 21:42:46

+1

這只是樣板ABI的東西,但用-O3編譯兩者,它可能會縮小一點。 –

+0

類似奇怪的函數序言:http://stackoverflow.com/questions/3155257/gdb-what-is-the-mysterious-assembly-code –

回答

3

你似乎在編譯舊的3.x系列gcc,你最好升級。較新的版本不會調用alloca。我懷疑alloca的特定版本可能會使用註冊約定,因此mov 0x10,%eax可能會爲該調用設置參數。

__main是在crtbegin.o中定義的啓動函數,它執行全局構造函數並使用將運行全局析構函數的atexit註冊函數。

另外請注意main得到了特殊待遇,如堆棧對齊碼和上述初始化。如果您只是對代碼生成問題感興趣,那麼反而比較一個「簡單」函數可能是一個好主意。

0

一個注意到在上面的例子中編譯器調用puts,而在下面的例子中是printf。我會懷疑你已經在頂部的例子中進行了優化,而不是在下面的例子中。

它也可能是一個調試與非調試版本。