__asm__("mnemonic1 %2 %0\n\t" "mnemonic2 %3 %1"
: "=出力reg文字"(出力変数), "=出力reg文字2"(出力変数)
: "入力reg文字"(入力変数), 入力reg文字2"(入力変数)
: "退避したいレジスタ1", "退避したいレジスタ2"
);
gcc manual Extensions to the C Language Family Extended Asm参照 下記では特に断わりがない場合上記linkから引用memo:
- asmより__asm__と書いた方がよい。
- mnemonicを複数に分かれる場合は"\n\t"で区切る。
- all output operands' constraints must use "=".
- outputがなくても":"inputがある場合は記述する。
- reg文字(レジスタを表わす文字)
- g 任意の汎用レジスタ
- a EAXレジスタ
- b EBXレジスタ
- c ECXレジスタ
- d EDXレジスタ
- D DIレジスタ
- S SIレジスタ
- f 浮動小数点レジスタ
- m メモリアクセス
- 入出力用に指定した上記のレジスタやメモリは、左から指定した順に、アセンブリコードの中では %0, %1, %2..で表記
manualのどこに書いてあるのか不明。 instead of a percentage sign followed by the operand number.から読み取れなくもないが突然でてくるような。。。で調べたところ、internals manualに記述が。。GCC Internals Manual Machine Descriptions Output Templates and Operand Substitutionから引用
The character `%' is used to specify where to substitute an operand; it can also be used to identify places where different variants of the assembler require different syntax. In the simplest case, a `%' followed by a digit n says to output operand n at that point in the string.
cf. GCCでインラインアセンブリを使用する方法と留意点等 for x86 - 入出力用に指定したレジスタが特定のレジスタ名で、オペランドにレジスタ名を使いたい場合、IA32では%eaxという形になるので%%eaxと記述する。
If you refer to a particular hardware register from the assembler code, you will probably have to list the register after the third colon to tell the compiler the register's value is modified. In some assemblers, the register names begin with `%'; to produce one `%' in the assembler code, you must write `%%' in the input.
- "アセンブリコード"によって内容が破損してしまうレジスタを3番目の: の後に書いておくと、そのレジスタの内容が事前に退避、事後に復帰されるようにコンパイラが自動でコード生成してくれる。これによってレジスタの退避、復帰を省いて書くことができる。
- 出力と入力、コードによって破損するレジスタは何れも省略可能である。省略する場合、その部分は空白にしておく。曖昧でなければ : も省略可能
- GCCの最適化により文の位置が変らないようにするには__asm__ __volatile__, asm volatileのようにvolatileを併用する。
- 予測不可能なメモリ破壊を防ぐアセンブリコードを書く場合、待避したいレジスタの所に "memory"と記述する。さらに、入出力オペランドとして使われていないメモリの予測不可能
な破壊を行なわないようにするには、asmではなくasm volatileを使い、待避したいレジスタの所に"memory"と記述する。
You will also want to add the 'volatile' keyword if the memory affected is not listed in the inputs or outputs of the asm, as the 'memory' clobber does not count as a side-effect of the asm. If you know how large the accessed memory is, you can add it as input or output but if this is not known, you should add 'memory'.