这篇笔记录的内容来自GCC手册中关于内嵌汇编的说明。
通过asm关键字,可以实现在C/C++代码中插入汇编代码,GCC提供了两种格式的内嵌汇编代码:1)基本asm汇编(无操作数);2)扩展asm汇编(有一个或多个操作数)。推荐使用扩展asm汇编,但也有些场景是必须使用基本asm汇编来完成。
基本asm汇编
基本asm汇编语法如下:
asm [ volatile ] ( AssemblerInstructions )
asm是GNU扩展的关键字,如果可以使用__asm__(对编译选项有要求),那么建议使用__asm__(手册上是这么介绍的,但是我们可以简单的将这二者认为是一样的)。
参数
AssemblerInstructions就是汇编代码,它就是个纯粹的字符串,GCC对其内容不做解释,它会被交给汇编程序处理。代码中通常用类似如下的写法来表示。
asm ("mov r0, r1\n\t"
"add r0, r2\n\t");
说明
使用扩展asm汇编往往可以生成更加高效的代码,但是有些场景是必须由基本asm汇编来完成的,比如:扩展asm汇编必须在C/C++函数内部,但是基本asm汇编可以独立在函数外,使用基本asm汇编可以在函数外定义宏,甚至实现某个函数;
基本asm汇编有很多的局限性,比如:如果在基本asm汇编代码中需要修改了某个寄存器,那么必须在执行前西先保存现场,执行完毕后再恢复现场,否则等基本asm汇编执行完毕后,GCC并不知到该寄存器的内容已经发生了变化,那么随后的程序大概率无法正确运行。上述的保护和恢复现场都必须由程序员在基本asm汇编中自己实现,很麻烦,使用扩展asm汇编可以高效洁净的解决这一问题。
扩展asm汇编
基本asm汇编只能包含语句,而扩展asm汇编却可以指定指令的操作数,可以让汇编指令和C变量有更好的互动。扩展asm语法如下:
asm [volatile] ( AssemblerTemplate
: OutputOperands
[ : InputOperands
[ : Clobbers ] ])
asm [volatile] goto ( AssemblerTemplat