GCCの埋め込みコンパイルに関するまとめ
2396 ワード
最近はGCCの組み込みコンパイルを使うかもしれませんので、少しまとめて、皆さんに分かち合います。
参考のURLを皆さんに共有します。
http://www.ibiblio.org/gferg/ldp/GCC-Inline-Assembly-HOWTO.html#s2
http://www.cnblogs.com/whutzhou/articles/2638498.html この文章は前の文章に対する翻訳です。
https://gcc.gnu.org/onlinedocs/gcc.pdf
GCCでは、基本的な内連結アセンブリ文(baic inline asm statement)と拡張内連結アセンブリ文(exteded inline asm statement)があります。基本的なインラインコンパイルにはオペランドは含まれません。一方、インラインコンパイル文の1つまたは複数のオペランドは拡張されます。
まず、基本的な国内連合の編纂文の形式を見てみます。
上記の問題があるからこそ、私達の次のテーマを引き出しました。
まず拡張されたコンパイル文の形式を見ます。
参考のURLを皆さんに共有します。
http://www.ibiblio.org/gferg/ldp/GCC-Inline-Assembly-HOWTO.html#s2
http://www.cnblogs.com/whutzhou/articles/2638498.html この文章は前の文章に対する翻訳です。
https://gcc.gnu.org/onlinedocs/gcc.pdf
GCCでは、基本的な内連結アセンブリ文(baic inline asm statement)と拡張内連結アセンブリ文(exteded inline asm statement)があります。基本的なインラインコンパイルにはオペランドは含まれません。一方、インラインコンパイル文の1つまたは複数のオペランドは拡張されます。
まず、基本的な国内連合の編纂文の形式を見てみます。
asm("assembly code");
もう一つ簡単な例をあげます。asm("movl %ecx %eax");
この例の形式は非常に簡単で、ecxの値をeaxに移すことです。上記の例を通して、基本的な内連結文はまず「_asm_u u」または「asm」のキーワードから始まります。括弧を通じて、アセンブリ文の範囲を指定します。二重引用符と「t」の方法で、アセンブリ文を分離します。形式は以下の通りです。 __asm__ ("movl %eax, %ebx
\t"
"movl $56, %esi
\t"
"movl %ecx, $label(%edx,%ebx,$4)
\t"
"movb %ah, (%ebx)");
上記のアセンブリ文を「;」で区切ることもできます。上記のアセンブリ文は以下のように書き換えられます。 __asm__ ("movl %eax, %ebx;"
"movl $56, %esi;"
"movl %ecx, $label(%edx,%ebx,$4);"
"movb %ah, (%ebx);");
しかし、上記のコンパイラ文は使用中に問題があります。一つの主要な問題はGCCがレジスタの値の変化を知らないことです。特にコンパイラがコードを最適化するとき、コンパイラは変数を格納するレジスタは、それを変えずに自分の最適化を継続します。このような状況を避けるために、レジスタの値を変えないか、あるいは、レジスターの値を変えないようにします。アセンブリ関数が戻る前に、レジスタの使用前の値を還元したり、コードの崩壊を待っています。 上記の問題があるからこそ、私達の次のテーマを引き出しました。
まず拡張されたコンパイル文の形式を見ます。
<pre name="code" class="cpp"><pre name="code" class="cpp"> asm ( assembler template
: output operands /* optional */
: input operands /* optional */
: list of clobbered registers /* optional */
);
扩展汇编语句共包括四个参数,分别是汇编语句模板、输出操作数、输入操作数以及 被破坏寄存器的列表,其中除第一个外,后三个均可以省略。虽然参数可以不填,位置却要留在那(就像for循环那样),一个最简单的扩展内联汇编语句形式如下:
上記の形式の分析により、拡張されたインラインアセンブル文は関数呼び出しに似ています。入力操作数は関数パラメータに似ています。出力操作数は関数戻り値に似ています。asm ( assembler template : : : );
ここで注意したいのは、入出力操作数が、破壊レジスタのリストに追加される必要がないことです。