Snippets 的に書いてみます。
オリジナルはこちら
http://www.barik.net/archive/2004/11/25/185507/
Source And Destination
%eax を %ebx にコピー
mov %eax, %ebx
GCC Syntax
Inline Assembly の書き方
asm ( assembler template
: output operands
: input operands
: list of clobbered registers
);
Simple Inline Assembly
asm ("shrl $8, %0"
: "=r" (answer)
: "r" (operand)
: "cc");
shrl(右シフト命令)を実行するためのアセンブラ。そのインプットが operand (Cの変数)で出力が answer。ダブルクオートの中身は、使用するレジスタ。r は特定のレジスタを指定せず動的に割り当てる。出力には = を書きましょう。cc は実行条件。$8 = 8ビットシフト(たぶん)。
Optimization
コンパイラに最適化を任せると良いけど、アセンブラで書いた方がメリットがある例としてMSBの求める。
int msb(int number)
{
asm ("bsrl %1, %0"
: "=r" (position)
: "r" (number));
return position
}
を for で書くと大変でしょ?っとことで。
long i;
for (i = (number >> 1),
position = 0; i != 0; ++position)
i >>= 1;
どうしてこうなった
カーネルコードでアセンブラ読むのをいつもあきらめてたので、そろそろ調べようかと思いまして。bsrl で検索したわけで。読みたかったのはこちら。
static inline int fls(int x)
{
int r;
#ifdef CONFIG_X86_CMOV
asm("bsrl %1,%0\n\t"
"cmovzl %2,%0"
: "=&r" (r) : "rm" (x), "rm" (-1));
#else
asm("bsrl %1,%0\n\t"
"jnz 1f\n\t"
"movl $-1,%0\n"
"1:" : "=r" (r) : "rm" (x));
#endif
return r + 1;
}
メモ:"m" はスタティックメモリ。"&"はインプットとアウトプットを別のレジスタにする。
上のコードを crash で見るとこんな感じでコンパイルされてる。
mov $0xffffffff,%ebx
bsr %r8d,%eax
cmove %ebx,%eax
関数が inline されているので、%r8d = "rm" (x)
の代入部は呼び出し側のコードで都度変わるので省略。
合わせて読みたい
こちらもオリジナルのサイトから。感謝の気持ちが止まらない。
その他、ARMだけど。
そして日本語が一番詳しかったとか orz