IAR EWARMで動作確認。GCCインラインアセンブラ構文を採用しており、他でもだいたい同じっぽい。VC++でのx86のインラインアセンブラに比べるとちょっとC言語の変数にアクセスする記法が分かりにくいかも。
基本
VC++と同様に__asmキーワードを用いてインラインアセンブラのコードを書くことができる。ただし、記法は少し異なる。(括弧とか引用符とかセミコロンとか)
__asm ("add r0, r1, r2");
C言語の変数へのアクセス
VC++では何気なく記述することができたが、GCCインラインアセンブラ構文の場合は出力リスト、入力リストで明示しなければならない。
__asm volatile( "add %[result], %[input1], %[input2]" : [result] "=r" (c) // 出力リスト : [input1] "r" (a), [input2] "r" (b) // 入力リスト : // 破壊レジスタリスト );
上の例で、
- %[result], %[input1], %[input2] はテンプレート。その下の出力リスト、入力リストでC言語の変数が指定される。
- 出力リスト、入力リストは、[シンボル名] "制約子" (C言語変数名) の形式で、コンマ区切り。
- シンボル名は適当な名前を自由に付ける。
- シンボル名を省略した場合は、%1,%2,%3...のようになる。
- 制約子はアクセスの制約を指定する。
- 制約子の"="は書き込み専用を示す。"+"なら読み書き両用。
- 制約子の"r"は汎用レジスタを示す。
- 破壊レジスタリストは、破壊してしまうレジスタ名を列挙する。
- 破壊レジスタリストは、: "r0", "r1" のように、""囲み、コンマ区切りで書く。
- 破壊レジスタリストで、”cc”は条件レジスタの破壊を示す。
- 破壊レジスタリストで、”memory”は未知のメモリの破壊を示す。
足し算のコード
x86インラインアセンブラ - 滴了庵日録の記事で書いたサンプルと同等の内容のコード。
#include<stdio.h> int main(void) { int a, b, c; a = 10; b = 20; // c = a + b __asm volatile( "add %[result], %[input1], %[input2]" : [result] "=r" (c) : [input1] "r" (a), [input2] "r" (b) ); printf("c = %d\n", c); while(1){;} return 0; }