9. 内嵌汇编

第07章详细介绍了汇编源程序的语法和编写方式。还有另外一种使用更广泛的编写汇编程序的方式——内嵌汇编(Inline Assembly)。内嵌汇编是可以直接在C/C++语言中插入的汇编程序,它实现了汇编语言和高级语言C/C++的混合编程。当在高级语言中要实现一些高级语言没有的功能,或者提高程序局部代码的执行效率,都可以考虑内嵌汇编的方式。本章将详细介绍内嵌汇编的语法规则和编写示例。

内嵌汇编标识为asm(),或称模板,用于通知编译器括号内的代码是内嵌汇编程序,需要特殊处理。括号内部有内嵌汇编自己专门的语法格式。比如可以在一个C语言文件中嵌入一个asm()标识,并在其括号内使用LoongArch汇编伪指令move完成变量赋值操作,即ret=src。

asm("move %0,%1\n\y":"=r"(ret):"r"(src));

这里src和ret都是C语言中的变量。src在内嵌汇编中作为输入操作数;ret在内嵌汇编中作为输出操作数,其修饰符“=r”中的“=”表明变量ret是个输出操作数。变量src和ret的修饰符中的“r”全称为relation,即指明此变量要对应一个固定的寄存器。指令中的%0和%1称为占位符(顾名思义,占位符就是先占住一个固定的位置,等待往其中添加内容的符号),分别对应变量ret和src。变量与LoongArch寄存器的最终对应关系由GCC编译器自动处理,处理后的结果可以是下面展示的两条数据加载指令和一条加法指令。

ld.d    %t1, .src
ld.d    $t2, .ret
addi.d  $t2, %r1, 0

可以看出,相对于汇编源程序,编写内嵌汇编省去了编写加载变量到寄存器的过程,也不用考虑使用哪个寄存器。这些细节工作都交给GCC编译器完成。内嵌汇编可以使用LoongArch中的大部分指令和伪指令,操作数既可以是寄存器也可以是C语言变量,可方便我们更快捷地编写程序。接下来将详细介绍内嵌汇编的基本格式。