定义__asm块作为C宏

Microsoft 专用

C 宏用于插入程序集代码提供了一种简便方式。源代码,但是,它们要求额外的问题,因为宏展开到一个逻辑行。若要创建无困难宏,请遵循以下规则:

  • __asm 块括在大括号。

  • 将在每个程序集指令前面的 __asm 关键字。

  • 使用旧式 C 注释 ( /* comment */) 而不是程序集的注释 ( ; comment) 或单行注释 C ( // comment)。

若要声明,下面的示例定义一个简单的宏:

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

乍看上去,最后三个 __asm 关键字是多余。,因为宏展开为单个行,,但它们是必需的:

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

第三个和第四个 __asm 关键字需要为一个语句分隔符。在 __asm 唯一识别的语句块分隔符是换行符和 __asm 关键字。由于作为宏定义的块是一个逻辑行,必须使用 __asm的每个指令。

大括号非常重要。如果省略它们,编译器可由有关同一行的 C 或 C++ 语句混淆在宏调用右侧。不是右大括号,编译器无法告诉程序集代码位置停止,并且,它看到 C 或 C++ 语句,在 __asm 块作为程序集指令之后。

从分号的程序集样式注释 (;) 开始继续行尾。这在宏始终会出现问题,因为编译器在注释后忽略所有内容,与逻辑行尾。也是如此的单行 C 或 C++ 注释 ( // comment)。若要防止错误,请使用旧式 C 注释 ( /* comment */) 在 __asm 块定义为宏。

,并且当 C++. 宏能够带参数, __asm 块写入。不同于普通 C 宏,但是, __asm 宏不能返回值。这样您就可以在 C 或 C++ 表达式不能使用这些宏。

注意不进行差异地调用此类型宏。例如,如果调用函数中的程序集语言的宏声明与 __fastcall 约定可能导致意外的结果。(请参见 使用和保留注册在内联程序集。)

特定于 Microsoft 的结尾

请参见

参考

内联汇编