在各种高级语言大行其道的今天为什么要用汇编呢?其实主要的原因有:第一,在C语言在关键地方嵌入汇编可以获得最大的性能提升,比如说一些关键算法;第二,实现硬件相关的功能(这点嵌入式开发经常用到)。第三,不能用C语言实现的特性可以用汇编实现,比如说可以利用lock指令来实现原子操作。
本文介绍了如何把汇编语言嵌入到c语言中的基础,然后给了2个例子。
在数据库中,为了实现一些特殊的操作,比如tas锁,需要借助汇编来完成。比如PostgreSQL中的tas锁就是用汇编写的。那么如何用c和汇编混合编程呢?先介绍一下基本语法,c语言中嵌入汇编的语法如下:
asm [volatile] ( AssemblerTemplate
: OutputOperands
[ : InputOperands
[ : Clobbers ] ])
asm
:标志一段嵌入式汇编的开始
volatile
:关闭编译器优化,这样就就不会把某些编译器认为无效的汇编删掉
AssemblerTemplate
:用于生成汇编的模板,里面包含了汇编代码和一些占位符
OutputOperands
:在汇编中修改的c程序中的变量,用逗号分隔
InputOperands
:在汇编中读取的c程序中的变量,用逗号分隔
Clobbers
:除了在OutputOperands列出的之外被汇编修改的register或其他的值
下面分别介绍一下上述内容
AssemblerTemplate
汇编模板实际上是一个字符串,比如
" cmpb $0,%1 \n"
" jne 1f \n"
" lock \n"
" xchgb %0,%1 \n"
里面包含了对OutputOperands
、InputOperands
的引用。接下来编译器会把汇编魔板中的引用等等变换为实际的汇编指令。在汇编模板中除了输入汇编指令之外,还可以有一些特殊符号,特殊符号表示了其他的含义:
%n
:引用OutputOperands
、InputOperands
中的第几个值
%%
:在汇编中输出一个%
符号
%=
:输出一个数字,每次都是不同的。一般用来作为goto标签。
%{
:输出{
%|
:输出|
%}
:输出}
OutputOperands
OutputOperands
的语法如下:
[ [asmSymbolicName] ] constraint (cvariablename)
asmSymbolicName
asmSymbolicName
asm符号名称,如果asm模板里面用%[Value]
来指定了一个名称。那么可以在OutputOperands
里面用[ [asmSymbolicName] ] constraint (cvariablename)
映射到具体的c程序变量名。比如:
int a,b;