Intel386およびAMD x86-64オプション

岸 哲夫

 組み込み用途の場合,IA32以外のプロセッサも多く使用されるが,サーバ用途やクロス開発環境の用途では,LinuxはIntel 386とAMD x86-64で動かしていることが多いだろう.今回は,この連載の最終回として,Intel 386 と AMD x86-64 オプションについて説明する. (筆者)

space

-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について解説する新連載を始める予定です.お楽しみに.


NEW記事内インデックス    連載インデックスはこちら   Interfaceのトップ
◆Intel386およびAMD x86-64オプション
リスト

Copyright 2005 岸 哲夫

Copyright 1997-2005 CQ Publishing Co.,Ltd.