内联汇编语句

在扩展语言级别下,编译器支持 C 和 C++ 源代码语句中的嵌入式汇编代码段。

此扩展已实现用于一般系统编程代码以及最初用 GNU C 开发的操作系统内核和设备驱动程序。

关键字 asm 代表汇编代码。 在编译中使用严格的语言级别时,C 编译器将 asm 视为常规标识并将 __asm__asm__ 保留为关键字。 C++ 编译器始终识别 asm__asm__asm__ 关键字。

语法如下:

asm 语句语法 - 局部范围中的语句

读取语法图跳过可视语法图asm__asm__asm__volatile( code_format_string:输出:input:clobber )
input
读取语法图跳过可视语法图,修饰符constraint(C_expression)
output
读取语法图跳过可视语法图,修饰符constraint(C_expression)
易变变量
限定符 volatile 指示编译器仅对汇编块执行最少的优化。 编译器不能跨汇编块周围的隐式围栏移动任何指令。 请参阅示例 1 以获取详细用法信息。
code_format_string
code_format_stringasm 指令的源文本,并且是类似于 printf 格式说明符的字符串文字。

操作数以 %integer 格式引用,其中 integer 是指输入或输出操作数的序号。 请参阅 示例 1 以获取详细的用法信息。

为了提高可读性,可以为每个操作数指定一个括在方括号中的符号名称。 在汇编代码部分中,您可以 %[symbolic_name] 格式引用每个操作数,其中 symbolic_name 是在操作数列表中引用的。 您可以使用任何名称(包括现有 C 或 C++ 符号),因为符号名称与任何 C 或 C++ 标识无关。 但是,同一汇编语句中的两个操作数不能使用相同的符号名称。 请参阅 示例 2 ,以获取详细的用法信息。

输出
output 包含零个、一个或多个输出操作数,并将逗号用作分隔符。 每个操作包含一个 constraint(C_expression) 对。 输出操作数必须受 =+ 修饰符 (如下所述)约束,并且 (可选) 受附加 % & 修饰符约束。
input
input 包含零个、一个或多个输入操作数,并将逗号用作分隔符。 每个操作包含一个 constraint(C_expression) 对。
clobber
clobber 是括在双引号中的寄存器名称的逗号分隔列表。 如果 asm 指令更新未在 asm 语句的 输入输出 中列出的寄存器,那么这些寄存器必须列示为已关闭的寄存器。 以下寄存器名称有效:
r0 到 r31
通用寄存器
f0 到 f31
浮点寄存器
lr
链接寄存器
ctr
循环计数、减量和分支寄存器
fpscr
浮点状态和控制寄存器
xer
定点异常寄存器
cr0 到 cr7
条件寄存器。 示例 3 显示 clobber 中条件寄存器的典型用法。
v0 到 v31
向量寄存器(仅在所选处理器上)
除寄存器名称外,还会在 clobber 寄存器中列表中使用 ccmemoryccmemory 的用法信息如下所示:
抄送
如果汇编程序指令可以改变 cr0,请将 cc 添加到已关闭的寄存器列表中。
memory

如果汇编程序指令可以不可预测的方式更改内存位置,请将 memory 添加到 clobber 列表。 memory clobber 可确保编译器不会在其他内存引用之间移动汇编程序指令,并确保在完成组合件语句之后使用的任何数据都有效。

但是,memory clobber 会导致许多不必要的重新装入,从而减少硬件预取的优势。 因此,memory clobber 可能会降低性能,应谨慎使用。 有关详细用法信息,请参阅示例 4示例 1

修饰符
修饰符可以是下列其中一个操作数:
=
指示该操作数对于此指令是只写的。 先前的值将被废弃并替换为输出数据。
+
指示操作数由指令读取和写入。 请参阅示例 5 以获取详细用法信息。
&
指示使用输入操作数完成指令之前可以修改操作数;用作输入的寄存器不应在此处重用。
%
声明此指令对于此操作数和下一个操作数是可交换的。 这意味着在生成指令时,此操作数和下一个操作数的顺序可能被交换。 此修饰符可以用于输入或输出操作数,但不能在最后一个操作数上指定。 请参阅 示例 6 以获取详细的用法信息。
constraint
constraint 是一个字符串文字,描述允许的操作数的种类,每个约束一个字符。 支持下列配置:
a
使用作为寄存器中的索引地址或间接地址的地址操作数。
b
使用除零之外的通用寄存器。 一些指令对寄存器 0 的指定进行了特殊处理,如果编译器选择 r0,则不会按预期运行。 对于这些指令,指定 r0 并不意味着使用 r0。 相反,它意味着指定字面值 0。 请参阅 示例 7 ,以获取详细的用法信息。
c
使用 CTR 寄存器。
d
使用浮点寄存器。
f
使用浮点寄存器。 请参阅 示例 6 以获取详细的用法信息。
h
使用 CTR 或 LINK 寄存器。
l
使用链接寄存器 lr。
m
使用机器支持的内存操作数。 您可以将此约束用于 D(R) 格式的操作数,其中 D 是位移,R 是寄存器。 请参阅 示例 8 以获取详细的用法信息。
v
使用向量寄存器。
wa
使用任何 VSX 寄存器或配对 VSX 寄存器
x
使用条件寄存器字段 0 , cr0。
y
使用任何条件寄存器字段 cr0, cr1...cr7。
I , J , K和 L
常量值 折叠操作数中的表达式,并将该值替换为 % 说明符。 这些约束指定操作数的最大值,如下所示:
  • I — 带符号 16 位
  • J — 无符号 16 位左移 16 位
  • K — 无符号 16 位常量
  • L — 带符号 16 位左移 16 位
Q
使用从寄存器中偏移的内存操作数。
R
使用 AIX TOC 条目。
Z
使用通过寄存器中的已建立索引或间接寻址访问的内存操作数。
C_expression

C_expression 是 C 或 C++ 表达式,其值用作 asm 指令的操作数。 输出操作数必须是可修改的值。 C_expression 必须与针对它指定的约束一致。 例如,如果指定了 i ,那么操作数必须是整数常量。