アセンブラ命令の記述(#pragma inline_asm)
|
アセンブリ記述関数をインライン展開します。
[機能]
- | #pragma inline_asm で宣言したアセンブリ記述関数をインライン展開します。 |
- | アセンブラ埋め込みインライン関数の呼び出し規則は通常関数の呼び出し規則と同様です。 |
[方法]
- | 対象関数より前で#pragma inline_asm宣言を行います。 |
#pragma inline_asm [(]関数名 [,...][)]
|
[制限]
- | #pragma inline_asmは,関数本体の定義の前に指定してください。 |
- | #pragma inline_asmで指定した関数に対しても外部定義が生成されます。 |
- | コンパイラは#pragma inline_asmを指定した関数内に書いた文字列を,そのままアセンブラに渡します。 |
- | アセンブリ記述は,プリプロセッサの処理対象となります。このため,アセンブリ言語で使用される命令やレジスタと同じ名前のマクロを#defineでマクロ定義する場合は注意してください。iodefine.hをインクルードする場合は,アセンブリ記述関数をiodefine.hのインクルードより前に記述してください。 |
アセンブリ記述関数内にラベルを書くと,インライン展開の数だけ同一名のラベルが作られます。この場合は,次のいずれかの方法で対処してください。
- | アセンブリ記述のローカル・ラベルを使用してください。ローカル・ラベルはアセンブリ・ソースでは同一名ですが,アセンブラが自動的に別名に変換します。 |
ローカル・ラベルについては,「 .LOCAL」を参照してください。
- | 外部ラベルは1箇所のみに展開されるように記述してください。 |
- | アセンブリ記述関数を同じソースファイル内から呼び出す場合は,アセンブリ記述関数定義にstaticを指定し,1箇所のみからアセンブリ記述関数を呼び出してください。また,アセンブリ記述関数のアドレスを取得しないでください。 |
- | アセンブリ記述関数を同じソースファイル内から呼び出さない場合は,アセンブリ記述関数を外部関数としてください。 |
[使用例]
Cソースを以下に示します。
#pragma inline_asm func
void func(int x)
{
movw !_a, ax
}
#pragma inline_asm func1
static void __near func1(void) // 外部ラベル定義を含むinline_asm指定関数を同一ファイルから
{ // 呼び出す場合は,static __near関数とする。
.PUBLIC _label1
incw ax
_label1:
decw ax
}
#pragma inline_asm func2
void func2(void) // 外部ラベル定義を含むinline_asm指定関数を同一ファイルから
{ // 呼び出さない場合は,外部関数とする。
.PUBLIC _label2
decw ax
_label2:
incw ax
}
void main(void){
func(3);
func1(); // 外部ラベル定義を含むinline_asm指定関数を呼び出す。
}
|
コンパイラの出力アセンブリ・ソースは,以下のようになります。
.SECTION .textf,TEXTF
_func:
.STACK _func = 4
._line_top inline_asm
movw !_a, ax
._line_end inline_asm
ret
_func2:
.STACK _func2 = 4
._line_top inline_asm
.PUBLIC _label2
decw ax
_label2:
incw ax
._line_end inline_asm
ret
_main:
.STACK _main = 4
movw ax, #0x0003
._line_top inline_asm ; funcの展開コード
movw !_a, ax ;
._line_end inline_asm ;
._line_top inline_asm ; func1の展開コード
.PUBLIC _label1 ;
incw ax ;
_label1: ;
decw ax ;
._line_end inline_asm ;
ret
|