ASM格式:__asm__ __volatile__("Instruction List" : Output : Input : Clobber/Modify);
指令集、输出、输入、修改部分;
例如:linux中atomic64_read函数,如下:
static inline long long atomic64_read(const atomic64_t *v) {
register_pair rp;
asm volatile(
"lm %0, %N0, 0(%1)"
: "=&d" (rp) //由两部分组成,括号部分和引号部分,括号部分为为c/c++表达式,作为输出;其中括号部分的值来自于引号部分,可翻译为rp=&d,其中d为寄存器;编号为0;
: "a" (&v->counter), "m"(v->counter) //作为输入;其中a=&v->counter; "m"(v->counter) 表示从内存中取值;其中, "a" (&v->counter)作为编号为1的操作表达式, "m"(v->counter) 为编号为2的操作表达式;
)
return rp.pair;
}
内嵌汇编约束:
1. 输入/输出的引号约束如下,寄存器约束:
符号意义
r:I/O 表示使用一个通用寄存器,由GCC在%eax/%ax/%al, %ebx/%bx/%bl, %ecx/%cx/%cl, %edx/%dx/%dl中选取一个GCC认为合适的。
q:I/O 表示使用一个通用寄存器,和r的意义相同。
a:I/O 表示使用%eax / %ax / %al
b:I/O 表示使用%ebx / %bx / %bl
c:I/O 表示使用%ecx / %cx / %cl
d:I/O 表示使用%edx / %dx / %dl
D:I/O 表示使用%edi / %di
S:I/O 表示使用%esi / %si
f:I/O 表示使用浮点寄存器
t:I/O 表示使用第一个浮点寄存器
u:I/O 表示使用第二个浮点寄存器2. 内存约束
符号
m:I/O 表示使用系统所支持的任何一种内存方式,不需要借助寄存器3. 立即数约束
符号
i:I 表示输入表达式是一个立即数(整数),不需要借助任何寄存器F:I 表示输入表达式是一个立即数(浮点数),不需要借助任何寄存器
4. 通用约束
符号
g:I/O 表示可以使用通用寄存器,内存,立即数等任何一种处理方式。
0,1,2,3,4,5,6,7,8,9 I 表示和第n个操作表达式使用相同的寄存器/内存。5. 修饰符
符号
= O 表示此Output操作表达式是Write-Only的
+ O 表示此Output操作表达式是Read-Write的
& O 表示此Output操作表达式独占为其指定的寄存器;此修饰符的输出寄存器不可再被输入寄存器使用
% I 表示此Input操作表达式中的C/C++表达式可以和下一个Input操作表达式中的C/C++表达式互换6. 占位符(%)
Instruction List: 中%1, %0为占位符,分别替代表达式编号1和0;
atomic64_set(atomic64_t *v, long long i) {
register_pair rp = {.pair = i};
asm volatile(
" stm %1, %N1, 0(%2)"
: "=m" (v->counter)
: "d"(rp), "a" (&v->counter)
)
}