9 月 2010

在 64-bit 的 Linux 中,用 32-bit 的 gcc 產生 32-bit 的 binary…

噢!這個標題真是個亂七八糟的組合……XDD

看起來很好笑,但實際遇到就很難笑出來了。

在這樣的組合下,若是我們直接執行 gcc 的話,會有下列的錯誤訊息:

$ gcc test.c
/tmp/cc7YTML2.s: Assembler messages:
/tmp/cc7YTML2.s:13: Error: suffix or operands invalid for push'
/tmp/cc7YTML2.s:14: Error: suffix or operands invalid for '
/tmp/cc7YTML2.s:16: Error: suffix or operands invalid for push'
/tmp/cc7YTML2.s:25: Error: suffix or operands invalid for '
/tmp/cc7YTML2.s:26: Error: suffix or operands invalid for pop'</pre>
<p>會有這樣的錯誤訊息,主要是因為 gcc 產生了 32-bit 的 assembly file,餵給 as (assmebler);但此時系統裝的 as 卻是 64-bit 版的,因此預設會用 64-bit 的方式去組譯 32-bit 的 assembly,結果當然是出不來。</p>
<p>as 有個參數 -32’,可以強制 as 用 32-bit 的方式去組譯。我們可以把原本 gcc 幫我們做的動作拆成下列的分解動作,手動編譯 test.c:

$gcc -S test.c            # 編譯,產生 test.s
$as -32 -o test.o test.s  # 以 32-bit 模式組譯,產生 test.o
$gcc -o test.out test.o   # 產生執行檔

但每個程式這樣做不是很麻煩嗎(笑)?還好,gcc 另外提供了一個方法,可以把參數送給 as:

$gcc -Wa,-32 -o test.out test.c

要注意 32 前面的減號不能省略。這樣做就 ok 了。