ZHCUAQ1F july 2015 – april 2023
定义 C 可调用过程
label .cproc [argument1 [, argument2 , …]]
.endproc
使用 .cproc/.endproc 指令对来分隔代码段,您希望汇编优化器优化该代码段并将其视为 C/C++ 可调用函数。该代码段称为过程。cproc 指令与 .proc 指令的相似之处在于,您在段的开头使用 .cproc,在段的末尾使用 .endproc。通过这种方法,您可以设置要优化的汇编代码段,例如函数。这些指令必须成对使用;如果没有相应的 .endproc,则不要使用 .cproc。使用 .cproc 指令指定标签。线性汇编文件中可以有多个过程。
.cproc 指令与 .proc 指令的不同之处在于,编译器将 .cproc 区域视为 C/C++ 可调用函数。汇编优化器会在 .cproc 区域中自动执行一些操作,以使函数符合 C/C++ 调用约定和 C/C++ 寄存器使用约定。
这些操作包括:
使用可选的 argument 表示函数参数。参数条目与 C/C++ 函数中声明的参数非常相似。.cproc 指令的参数可以是以下类型:
frame .cproc arg1
汇编优化器要么将 arg1 分配给 A4,要么将 arg1 分配给不同的寄存器(例如 B7)和 MV A4,B7 是自动生成的。
例如,.cproc 定义如下:
_fcn: .cproc arg1, arg2hi:arg2lo, arg3, B6, arg5, B9:B8
...
.return res
...
.endproc
对应于声明如下的 C 函数:
int fcn(int arg1, long arg2, int arg3, int arg4, int arg5, long arg6);
在此示例中,.cproc 的第四个参数是寄存器 B6。这是允许的,因为在 B6 中传递了 C/C++ 调用约定中的第四个参数。.cproc 的第六个参数是实际的寄存器对 B9:B8。这是允许的,因为 C/C++ 调用约定中的第六个参数在 B8 或 B9:B8 中传递了 long。
如果从 C++ 源代码调用过程,则必须为过程标签使用适当的链接名。否则,您可以使用 extern C 声明强制使用 C 命名约定。请参阅 节 7.12 和 节 8.6 了解详情。
当 .endproc 与 .cproc 指令一起使用时,它不能有参数。.cproc 区域的 live out 集由出现在 .cproc 区域中的任何 .return 指令确定。(如果值是在过程之前或过程中定义的,并且用作过程的输出,则它为 live out。)从 .cproc 区域返回值由 .return 指令处理。返回分支是在 .cproc 区域中自动生成的。有关更多信息,请参阅 .return 主题。
只有过程中的代码会被优化。汇编优化器会将过程之外的任何代码复制到输出文件,而不会对其进行修改。请参阅节 5.4.1,了解 .cproc 区域中不能出现的指令类型列表。
以下是使用了 .cproc 和 .endproc 的示例:
_if_then: .cproc a, cword, mask, theta
.reg cond, if, ai, sum, cntr
MVK 32,cntr ; cntr = 32
ZERO sum ; sum = 0
LOOP:
AND cword,mask,cond ; cond = codeword & mask
[cond] MVK 1,cond ; !(!(cond))
CMPEQ theta,cond,if ; (theta == !(!(cond)))
LDH *a++,ai ; a[i]
[if] ADD sum,ai,sum ; sum += a[i]
[!if] SUB sum,ai,sum ; sum -= a[i]
SHL mask,1,mask ; mask = mask << 1
[cntr] ADD -1,cntr,cntr ; decrement counter
[cntr] B LOOP ; for LOOP
.return sum
.endproc