●
-masm=dialect
dialectとしてintel,attが使用できます.特に指定しなければ,デフォルト値はattです.この2種の仕様では文法が違います.最終的なコードは変わりません.
例 定数値をレジスタに入れる場合
mov eax,10(Intel系)
movl $10,%eax(ATT系)
では,実際にコードで比較してみます.
# gcc test236.c -masm=intel -S
# gcc test236.c -masm=att -S
リスト1,リスト2に生成されたアセンブラを,リスト3に元のソースを示します.
標準的なアセンブラはATTの文法で書かれていますが.Intelの文法で慣れているなら,それを使ってみましょう.
●
-mieee-fp,-mno-ieee-fp
このオプションでコンパイラがIEEE浮動小数点比較を使用するかどうかをコントロールできます.
ただし,プログラム・ソース中で明示的に使用したほうが混乱を招かなくてよいでしょう.
●
-msoft-float
このオプションを指定すると浮動小数点を,コプロセッサではなく,ライブラリで扱うことになります.ライブラリが存在しなければリンク・エラーになります.
●
-mno-fp-ret-in-387
このオプションを指定すると浮動小数点を,コプロセッサを使用せず,エミュレートするようになります.
●
-mno-fancy-math-387
このオプションはFreeBSD,OpenBSDおよびNetBSDでのデフォルトです.浮動小数点をエミュレートで扱います.
●
-malign-double,-mno-align-double
このオプションを指定するとdouble型の境界を調整します.
●
-m96bit-long-double,-m128bit-long-double
long-doubleを内部で扱う方法を指定するオプションです.デフォルトは-m128bit-long-doubleです.
●
-msvr3-shlib,-mno-svr3-shlib
bssやデータ・セグメントの扱いを指定するオプションですが,System Vリリース3だけで意味をもちます.
●
-mrtd
cdecl属性によりコンパイラは,引き数を渡す際に使われたスタック領域は呼び出した関数がPOPするものと,想定するようになります.このオプションを指定すると標準以外の動作が可能ですが,ほかのライブラリを呼び出す際には注意してください.
●
-mregparm=num
regparm属性により,コンパイラは最高でnumberによって指定される個数までの整数引き数を,スタックではなくEAX,EDX,ECXレジスタに入れて渡すようになります.
# gcc test238.c -S
# gcc test238.c -mregparm=3 -S
スタックで渡す方法で生成されたアセンブラをリスト4に,レジスタで渡すように生成されたアセンブラをリスト5に示します.また,元のソースをリスト6に示します.
引き数がレジスタに渡されていることがわかります.
●
-mpreferred-stack-boundary=num
デフォルトでは境界整列の値は,32ビット,64ビットでともに最小の値を使用しますが,このオプションで指定した値で境界整列することが可能です.
●
-mmmx,-mno-mmx,-msse,-mno-sse,-msse2,-mno-sse2,-msse3,-mno-sse3,-m3dnow,-mno-3dnow
このオプションはそれぞれのCPU機能を使用するためのものです.したがって,MMX機能がないものにこのオプションを付けても意味がありません.
●
-mpush-args,-mno-push-args
スタックにプッシュする方法を指定するオプションです.有効にすればSUB/MOVを使用することになり,効率が良くなります.
●
-maccumulate-outgoing-args
このオプションを指定するとより速く動作するコードを生成しますが,サイズは増加します.-mno-push-argsオプションも使用します.
●
-mthreads
Cygwin環境でスレッド処理を行いたい場合に指定するオプションです.
●
-mno-align-stringops
内部の文字列を整列させないためのオプションです.コードの大きさが多少小さくなる場合もあります.
●
-minline-all-stringops
このオプションを指定するとコードの増加を招くこともありますが,memcpy,strlenおよびmemsetに依存するコードの実行速度を改善することになります.
●
-momit-leaf-frame-pointer
このオプションを指定すると,レジスタの中にフレーム・ポインタを保持しません.フレーム・ポインタを保存し,セットアップし,復元する指示を避けます.
●
-m32,-m64
このオプションを指定すると,32ビットまたは64ビットの環境のためにコードを生成します.32ビット環境は,長い間までのint,およびポインタを32ビットに設定し,どのようなi386システムの上ででも動くコードを生成します.
64ビットの環境は32ビットと長い間までのintと64ビットまでのポインタを設定し,AMDのx86-64アーキテクチャのためにコードを生成します.
●
-mno-red-zone
このオプションを指定すると,x86-64コードの「レッドゾーン」を使いません. この「レッドゾーン」はx86-64 ABIによって管理されています.
●
-mcmodel=small
小さなコード・モデルのためにコードを生成します.プログラムとそのシンボルはアドレス空間の下の2Gバイトにおいてリンクされます.ポインタは64ビットです.プログラムは静的であるか,動的にリンクされることができます.これはデフォルト・コード・モデルです.
●
-mcmodel=kernel
カーネル・コード・モデルのためにコードを生成します.カーネルはネガティブにおいてアドレス空間の2Gバイトを走ります.このモデルは,Linuxカーネル・コードのコンパイルに使用されます.
●
-mcmodel=medium
ミディアム・モデルのためにコードを生成します.プログラムはアドレス空間の下の2Gバイトにおいてリンクされますが,シンボルは限定されないアドレス空間に置くことが可能です.プログラムは静的ですが,動的にリンクすることが可能です.共用ライブラリを使用する際は注意が必要です.
●
-mcmodel=large
ラージ・モデルのためにコードを生成します.このモデルはセクションのアドレスとサイズについて限定されることはありません.しかし,現バージョンではサポートされません.
* *
以上で,GCCに関する説明は終了です.
GCCのオプションは今まで述べてきたようにたくさんありますが,これまでに説明したとおり,数々のオプションを組み合わせて,納得のいく動作をさせ,システム開発に役立つように使用してみてください.
次回からは,GDBについて解説する新連載を始める予定です.お楽しみに.