インラインアセンブラ

インラインアセンブラ（）は、主にC言語やC++などで書かれたプログラムの中にアセンブリ言語によるプログラムを埋め込むことができるようにする、コンパイラの機能である。
概要.
コンパイラの一機能を指しており、高水準言語で書かれたソースコードに埋めこまれたアセンブリ言語によるコードも機械語に変換する機能のこと。
この機能があれば、アセンブリ言語で書かれたコードをわざわざ別途アセンブラでアセンブル（機械語に変換）してリンクするという手間が省ける。特定のプロセッサが持つ特殊な拡張命令も使えるというメリットや、高速化が図れるなどのメリットがある。
一方デメリットとして、機種に強く依存したアセンブリ言語のコードをソースコードに含んでしまうことになるため、C言語などの高級言語の強みであるソースレベル互換性が低下する。
インラインアセンブラを利用する目的には次のようなものがある。
最適化の例とプロセッサ固有命令の例.
x86のFPUを利用して変数xのタンジェントを計算するD言語で記述されたインラインアセンブラの例。x86系プロセッサで利用可能な円周率の近似値を得るためのcodice_1命令を利用でき、コンパイラが浮動小数点を用いた場合より高速である。
// 変数xのタンジェントを計算する
real tan(real x)
 asm
 fld x[EBP] ; // xをロード
 fxam ; // 不正な値の検査
 fstsw AX ;
 sahf ;
 jc trigerr ; // xはNAN(非数)、無限、または空
 // 387は非正規化数を扱えない
SC18: fptan ;
 fstp ST(0) ; // dump X, which is always 1
 fstsw AX ;
 sahf ;
 jnp Lret ; // C2 = 1 (xは範囲外)
 // argument reductionしてxを有効範囲内に収める
 fldpi ;
 fxch ;
SC17: fprem1 ;
 fstsw AX ;
 sahf ;
 jp SC17 ;
 fstp ST(1) ; // piをスタックから除去
 jmp SC18 ;
trigerr:
 return real.nan;
Lret:
システムコールの例.
メモリが保護されている環境でOSの機能を直接呼び出すことは一般的に不可能である。OSはユーザーモードより上位の特権モード(カーネルモード)で動作しており、OSにリクエストするためには（ソフトウェア）割り込みを利用する。これを行う機能をもつ高級言語はほとんどなく、システムコールのためのはインラインアセンブラを用いて記述されている。
下記のC言語によるサンプルにはシステムコールのラッパーも含まれる。一般的にはマクロと組み合わせて記述するが、ここでは説明のためにあえてマクロを利用していない。
基本的なインラインアセンブラの形式は非常に単純である。基本形は下記のとおり(GCCのみ、Visual Studio では __asm{ }の形式に直す必要がある)。
asm("アセンブリコード");
例:
asm("movl %ecx, %eax"); /* ecxの中身をeaxに移動する */
または
__asm__("movb %bh, (%eax)"); /* bhから1バイトをeaxが指し示すメモリに移動する */
codice_2とcodice_3はいずれも正しい。もしcodice_2というキーワードがソースコード中のほかのキーワードと重複している場合はcodice_3を利用してもよい。
extern int errno;
int funcname(int arg1, int *arg2, int arg3)
 int res;
 __asm__ volatile(
 "int $0x80" /* OSに命令を発行する */
 : "=a" (res) /* eaxの中身("a")を結果として返す */
 "+b" (arg1), /* arg1をebxに渡す ("b") */
 "+c" (arg2), /* arg2をecxに渡す ("c") */
 "+d" (arg3) /* arg3をedxに渡す ("d") */
 : "a" (128) /* システムコール番号をeaxに渡す ("a") */
 : "memory", "cc"); /* メモリと条件レジスタが修正されたことをコンパイラに通知する */
 /* エラーが発生した場合、OSは負数を返す。
 * エラーが発生するとラッパー関数は-1を返し、グローバル変数errnoに値をセットする */
 if (-125 <= res && res < 0) {
 errno = -res;
 res = -1;
 return res;