__asm ブロックの C マクロとしての定義

Microsoft 固有の仕様

C マクロは、アセンブリ コードをソース コードに挿入する便利な方法を提供しますが、マクロが 1 つの論理行に展開されるので、特別な注意が必要です。 問題のないマクロを作成するには、次の規則に従います。

  • __asm ブロックを中かっこで囲みます。

  • 各センブリ命令の前に __asm キーワードを配置します。

  • アセンブリ スタイルのコメント ( ; comment)、または 1 行の C のコメント ( // comment) ではなく、以前のスタイルの C のコメント ( /* comment */) を使用します。

説明のため、次の例では、単純なマクロを定義しています。

#define PORTIO __asm      \
/* Port output */         \
{                         \
   __asm mov al, 2        \
   __asm mov dx, 0xD007   \
   __asm out dx, al       \
}

一見すると、最後の 3 つの __asm キーワードは余分に見えます。 しかし、マクロは 1 行に展開されるため、これらは必要です。

__asm /* Port output */ { __asm mov al, 2  __asm mov dx, 0xD007 __asm out dx, al }

3 番目と 4 番目の __asm キーワードはステートメントの区切りとして必要です。 __asm ブロックで認識されるステートメント区切り記号は、改行文字と __asm キーワードのみです。 マクロとして定義されたブロックは 1 つの論理行なので、各命令を __asm で区切る必要があります。

中かっこも必須です。 これらを省略すると、マクロ呼び出しの右側にある同じ行の C または C++ ステートメントによってコンパイラが混乱する場合があります。 右中かっこを使用しないと、アセンブリ コードが停止する場所がコンパイラにより特定されず、__asm ブロックの後の C または C++ ステートメントがアセンブリ命令として認識されます。

セミコロン (;) で始まるアセンブリ スタイルのコメントは、行の最後まで続きます。 コンパイラはコメントの後、論理行の末尾までのすべてを無視するため、マクロで問題が発生します。 同じことが C または C++ の 1 行のコメント ( // comment) にも当てはまります。 エラーを防ぐため、マクロとして定義された __asm ブロックでは、以前のスタイルの C のコメント ( /* comment */) を使用します。

__asm C マクロとして書き込まれたブロックは、引数を受け取ります。 ただし、通常の C マクロと異なり __asm マクロは値を返しません。 そのため、C または C++ の式ではこのようなマクロを使用できません。

この型のマクロをむやみに呼び出さないようにご注意ください。 たとえば、__fastcall 規則で宣言された関数を使用してアセンブリ言語マクロを呼び出すと、予期しない結果が生じるおそれがあります。 (「インライン アセンブリでのレジスタの使用および保持」を参照して下さい。)

Microsoft 固有の仕様はここまで

関連項目

インライン アセンブラー