内联汇编语句(IBM 扩展)
在扩展语言级别下,编译器支持 C 和 C++ 源代码语句中的嵌入式汇编代码段。 此扩展已实现用于一般系统编程代码以及最初用 GNU C 开发的操作系统内核和设备驱动程序。
关键字 asm 代表汇编代码。 在编译中使用严格的语言级别时,C 编译器将 asm 视为常规标识并将 __asm 和 __asm__ 保留为关键字。 C++ 编译器始终识别 asm、__asm 和 __asm__ 关键字。
- 易变变量
- 限定符
volatile指示编译器仅对汇编块执行最少的优化。 编译器不能跨汇编块周围的隐式围栏移动任何指令。 请参阅示例 1 以获取详细用法信息。 - code_format_string
- code_format_string 是
asm指令的源文本,并且是类似于printf格式说明符的字符串文字。操作数以
%integer格式引用,其中 integer 是指输入或输出操作数的序号。 请参阅 示例 1 以获取详细的用法信息。为了提高可读性,可以为每个操作数指定一个括在方括号中的符号名称。 在汇编代码部分中,您可以
%[symbolic_name]格式引用每个操作数,其中 symbolic_name 是在操作数列表中引用的。 您可以使用任何名称(包括现有 C 或 C++ 符号),因为符号名称与任何 C 或 C++ 标识无关。 但是,同一汇编语句中的两个操作数不能使用相同的符号名称。 请参阅 示例 2 ,以获取详细的用法信息。 - 输出
- output 包含零个、一个或多个输出操作数,并将逗号用作分隔符。 每个操作包含一个
constraint(C_expression)对。 输出操作数必须受=或+修饰符 (如下所述)约束,并且 (可选) 受附加%或&修饰符约束。 - 输入
- input 包含零个、一个或多个输入操作数,并将逗号用作分隔符。 每个操作包含一个
constraint(C_expression)对。 - clobber
- clobber 是括在双引号中的寄存器名称的逗号分隔列表。 如果
asm指令更新未在asm语句的 输入 或 输出 中列出的寄存器,那么这些寄存器必须列示为已关闭的寄存器。 以下寄存器名称有效:- r0 到 r31
- 通用寄存器
- f0 到 f31
- 浮点寄存器
- lr
- 链接寄存器
- ctr
- 循环计数、减量和分支寄存器
- fpscr
- 浮点状态和控制寄存器
- xer
- 定点异常寄存器
- cr0 到 cr7
- 条件寄存器。 示例 3 显示 clobber 中条件寄存器的典型用法。
- v0 到 v31
- 向量寄存器(仅在所选处理器上)
除寄存器名称外,还会在 clobber 寄存器中列表中使用cc和memory。cc和memory的用法信息如下所示: - 修饰符
- 约束
- constraint 是一个字符串文字,描述允许的操作数的种类,每个约束一个字符。 支持下列配置:
- b
- 使用除零之外的通用寄存器。 一些指令对寄存器 0 的指定进行了特殊处理,如果编译器选择
r0,则不会按预期运行。 对于这些指令,指定r0并不意味着使用r0。 相反,它意味着指定字面值 0。 请参阅 示例 8 ,以获取详细的用法信息。 - c
- 使用 CTR 寄存器。
- d
- 使用浮点寄存器。
- f
- 使用浮点寄存器。 请参阅示例 7 以获取详细用法信息。
- g
- 使用通用寄存器、内存或立即操作数。 在 POWER ® 体系结构中,没有可互换使用寄存器,内存说明符或直接操作数的指令。 但是,在允许这样做的位置容许使用此约束。
- h
- 使用 CTR 或 LINK 寄存器。
- i
- 使用直接整数或字符串文字操作数。
- l
- 使用 CTR 寄存器。
- m
- 使用机器支持的内存操作数。 您可以将此约束用于
D(R)格式的操作数,其中D是位移,R是寄存器。 请参阅 示例 9 ,以获取详细的用法信息。 - n
- 使用直接整数。
- o
- 使用可偏移的内存操作数。 这意味着可以通过将整数添加到基地址来寻址内存操作数。 在 POWER 体系结构中,内存操作数始终是可偏移的,因此可以互换使用约束
o和m。 - r
- 使用通用寄存器。 请参阅 示例 5 以获取详细的用法信息。
- s
- 使用字符串文字操作数。
- v
- 使用向量寄存器。
- 0, 1, …8, 9
- 匹配约束。 在输出中分配与相应输入中相同的寄存器。
- I, J, K, L, M, N, O, P
- 常量值 折叠操作数中的表达式,并将该值替换为
%说明符。 这些约束指定操作数的最大值,如下所示:- I — 带符号 16 位
- J — 无符号 16 位左移 16 位
- K — 无符号 16 位常量
- L — 带符号 16 位左移 16 位
- M — 大于 31 的无符号常量
- N — 作为 2 的精确幂的无符号常量
- O — 零
- P — 带符号常量,其相反数是带符号的 16 位常量
- C_expression
C_expression 是 C 或 C++ 表达式,其值用作
asm指令的操作数。 输出操作数必须是可修改的值。 C_expression 必须与针对它指定的约束一致。 例如,如果指定了i,那么操作数必须是整数常量。
注: 如果在 输入 或 输出中使用了指针表达式,那么组合件指示信息将遵循 ANSI 别名判别规则 (请参阅 基于类型的别名判别 以获取更多信息)。 这意味着在指针表达式操作数中使用值的间接寻址应该与指针类型一致; 否则,必须在编译期间禁用 -qalias=ansi 选项。
