我無法準確再現您所看到的內容,但是在我的4.8.2版本的gcc中,該選項會影響此代碼使用的堆棧數量(請確保使用「緩衝區」來避免它被優化遠,並定爲沒有返回類型/參數類型的警告):
#include <stdio.h>
void foo(void)
{
char buffer[8];
buffer[0] = 'a';
buffer[1] = '\n';
buffer[2] = 0;
printf("my first program! %s\n", buffer);
}
int main()
{
foo();
return 0;
}
與-mpreferred堆疊邊界= 2和-mpreferred堆疊邊界= 4,並且將所生成的彙編程序之間的差異是編譯值得注意的是:
$ diff -u stb-2.s stb-4.s
--- stb-2.s 2014-04-10 09:00:39.546038191 +0100
+++ stb-4.s 2014-04-10 09:00:58.895108979 +0100
@@ -15,11 +15,11 @@
.cfi_offset 5, -8
movl %esp, %ebp
.cfi_def_cfa_register 5
- subl $16, %esp
- movb $97, -8(%ebp)
- movb $10, -7(%ebp)
- movb $0, -6(%ebp)
- leal -8(%ebp), %eax
+ subl $40, %esp
+ movb $97, -16(%ebp)
+ movb $10, -15(%ebp)
+ movb $0, -14(%ebp)
+ leal -16(%ebp), %eax
movl %eax, 4(%esp)
movl $.LC0, (%esp)
.LEHB0:
@@ -67,9 +67,10 @@
.cfi_offset 5, -8
movl %esp, %ebp
.cfi_def_cfa_register 5
+ andl $-16, %esp
call _Z3foov
movl $0, %eax
- popl %ebp
+ leave
.cfi_restore 5
.cfi_def_cfa 4, 4
ret
所以,至少在gcc中是4.8.2。對於x86-32,該選項有效。
當然,根據文檔的默認值是-mpreferred-stack-boundary = 2,所以也許這就是爲什麼你看不到「沒有」的任何區別(雖然在我的實驗中,它似乎是-mpreferred -stack邊界= 4)。 [瞬間通過]啊,默認值已經隨時間而改變了,所以4.4.2文檔在線說2,我的信息gcc爲4.8.2說了4,這就解釋了差異。
至於爲什麼你的代碼是分配12個字節的堆棧空間 - 看的printf怎麼叫:
movl $.LC0, (%esp)
call printf
如果編譯器,它會預先分配參數空間功能在開始通話的功能,而不是像在這種情況下那樣使用push $.LC0
。這並沒有太大的區別,但它至少在printf的另一端至少節省了一條清理指令(這使得在生成的代碼中處理堆棧相對偏移更容易,因爲編譯器不必跟蹤當前堆棧指針所在的位置 - 它始終位於函數開頭的序言代碼之後的一個恆定位置,一直到函數結尾)。由於無論如何都最終需要空間,因此「節省4個字節」毫無意義。
首先確保它是0xC,而不是0xC0。無論如何,這兩種方式都與其所提供的4個已完成的堆棧邊界相一致。函數可能需要比局部變量總和更多的堆棧,例如對於臨時數據和例如用於將數據傳遞給其他功能。 – nos
0xC0!= 0x0C ... –
但爲什麼它沒有執行子$ 0x8,$ esp – user3270649