インラインアセンブラとは?

最も低レベルなアセンブリ言語で記述されたコードを

C言語やAdaのような高級言語のソースコードに埋め込む機能のこと

使う目的

  • 最適化
最も性能に影響する部分を置き換えて、処理を高速化する。
  • プロセッサ固有の特殊な命令の利用
  • システムコールの呼び出し

書式

こんな感じで書く。__asm__キーワードが味噌。

__volatile__はコンパイラの最適化を避けて書いた通りに動いてもらうためのおまじない。
 void func(){
   __asm__  __volatile__("movb    $0x02, %ah¥n¥t"
                                  "testb     $0x3 , %al¥n¥t");
 }

上記は展開されるとこんな感じになるらしい。

アセンブラ命令

 void func(){
   #APP
       mobv $0x02,  %ah
       testb  $0x3  ,  %al
   #NO_APP
 }

拡張アセンブリ構文

インライン構文の中はレジスタを自由にいじれるけど、

レジスタの値を復元しないままだと困る事がある。あとぜき大事。

そのために拡張アセンブリ構文があって、色々設定出来る。

ただし、拡張アセンブリ構文ではアセンブラ命令の書き方が違うので注意。

__asm__ __volatile( アセンブラ命令の羅列
                           : 出力オペランド
                           : 入力オペランド
                           : 破壊されるレジスタのリスト
);

出力オペランド

インラインアセンブラの記述の前に下記のように変数が宣言されているとする
int ret;
入力オペランドで下記のように指定すると、簡単にアセンブラ命令部で使える
:"=r"(ret)
アセンブラ命令部では下記のように指定する
"movl %%eax, %0;
%0がretに対応している。%0とかは出力オペランドで指定した数に左右される。(連番)

「=」は修飾子と呼ばれ、「r」はオペランド制約と呼ばれる。意味はあとで。

入力オペランド

インラインアセンブラの記述の前に下記のように変数が宣言されているとする
int a,b,c;
入力オペランドで下記のように指定すると、簡単にアセンブラ命令部で使える
:"r"(a),"r"(b)
アセンブラ命令部では下記のように指定する
"movl %1, %%eax;
%1がaに対応している。%1は出力、入力オペランドで指定した数に左右される。(連番)

アセンブラ命令の羅列(拡張アセンブリ構文)

アセンブラ命令部では下記のように指定する
"movl %1, %%eax;
 addl %2, %%eax;
 movl %%eax, %0;" 
  • 拡張アセンブリ構文では続けて命令を書く場合は「;」で区切る
  • レジスタ名を指定する場合は「%%」を頭に付ける

破壊されるレジスタのリスト

ここに破壊されるレジスタ名を記述する
:"%eax"
これを付けとくとコンパイラはレジスタの破壊を回避してくれる

条件レジスタが破壊されるなら
:"%eax", "cc"
と「"cc"」を付ける。

メモリ破壊が起こり得る場合は
:"%eax", "memory"
と「"memory"」をつける

修飾子とは

細かい条件指定
  • 「=」は書き込み専用の意味
  • 「+」は読み書き両方
  • 「&」は入力オペランドが使い終わる前に変更されるオペランドを指す。

オペランド制約とは

変数をどのレジスタと結びつけるかの指定。主に英数字が割り当てられる。
  • 単純制約
  • マッチング制約
  • メモリ制約
  • その他の制約
と色々ある。

C++の構文をインラインアセンブラで書いたらどうなる?

加算

減算

除算

乗算

for文

while文

do while文

if文

最終更新:2011年04月09日 11:47