2015-10-16 43 views
0

根據這篇文章:linkC到大會轉換數據類型尺寸

在該C簡單的程序:

void function(int a, int b, int c) { 
     char x[10]; 
} 

void main() { 
     function(1, 2, 3); 
} 

我使用該命令獲取組件文件:

gcc -m32 -S -o example1.s example1.c 

,這是功能(功能)的結果:

function: 
.LFB0: 
     .cfi_startproc 
     pushl %ebp 
     .cfi_def_cfa_offset 8 
     .cfi_offset 5, -8 
     movl %esp, %ebp 
     .cfi_def_cfa_register 5 
     subl $16, %esp 
     nop 
     leave 
     .cfi_restore 5 
     .cfi_def_cfa 4, 4 
     ret 
     .cfi_endproc 

我的問題是,爲什麼這一行變成了:

subl $16, %esp 

在那裏我希望它是:

subl $10, %esp 

我使用卡里的linux 64

VENDOR_ID:GenuineIntel

型號名稱:Intel(R)Core(TM)i3 CPU M 350 @ 2.27GHz

架構:x86_64的

CPU運算模式(一個或多個):32位,64位

字節順序:小端

+0

這可能是優化了 – VermillionAzure

回答

2

這實際上是堆棧對齊。

gcc(1)手冊:

-mpreferred堆疊邊界= NUM​​

試圖保持對準,以凸起爲num字節邊界的2堆棧邊界。如果未指定-mpreferred-stack-boundary,則缺省值爲4(16字節或128位)。

GCC正在對齊堆棧的底部,使其位於16字節的邊界上。

實際的佈局是:

x[9] 
... 
x[0] 
padding[5] 
... 
padding[0] <-- $esp 
+0

所以它應該是'subl $ 12%esp'不'subl $ 16%esp'? –

+0

你在哪裏得到12? 2^4是16.如果你嘗試分配17個字節,你會得到'subl $ 32,%esp'。 – Steven

+0

thanx Stebalien,我明白了! –