内联汇编约束 + 示例代码速查表
1. 输出约束
| 约束 | 含义 | 示例 |
|---|---|---|
"=r" | 输出到寄存器 | c int out; asm("movl $5, %0" : "=r"(out)); |
"=m" | 输出到内存 | c int out; asm("movl $5, %0" : "=m"(out)); |
"=a" | 输出到 eax | c int out; asm("movl $5, %%eax\n\t movl %%eax, %0" : "=a"(out)); |
"=d" | 输出到 edx | c int out; asm("movl $5, %%edx" : "=d"(out)); |
"=g" | 输出到通用寄存器或内存 | c int out; asm("movl $5, %0" : "=g"(out)); |
2. 输入约束
| 约束 | 含义 | 示例 |
|---|---|---|
"r" | 输入到寄存器 | c int a=3; asm("addl %1, %0" : "=r"(a) : "r"(5)); |
"m" | 输入在内存 | c int a=3; asm("addl %1, %0" : "=r"(a) : "m"(a)); |
"a" | 输入强制放在 eax | c int a=5; int out; asm("movl %%eax, %0" : "=r"(out) : "a"(a)); |
"b" | 输入放在 ebx | c int a=5; asm("movl %0, %%ebx" :: "b"(a)); |
"c" | 输入放在 ecx | c int n=10; asm("loop_label: loop loop_label" :: "c"(n)); |
"d" | 输入放在 edx | c int v=7; asm("movl %0, %%edx" :: "d"(v)); |
"S" | 输入放在 esi | c char *p; asm("mov %0, %%esi" :: "S"(p)); |
"D" | 输入放在 edi | c char *p; asm("mov %0, %%edi" :: "D"(p)); |
"i" | 编译期立即数 | c int x; asm("movl $10, %0" : "=r"(x)); |
"n" | 常量立即数 | c int x; asm("addl %1, %0" : "=r"(x) : "n"(4)); |
"E" | 范围立即数(如移位 0–31) | c int x=5; asm("shll $3, %0" : "+r"(x)); |
"F" | 浮点常量 | c double d; asm("fldz" : "=t"(d)); |
"p" | 有效地址(指针) | c int arr[4]; asm("lea %0, %%eax" :: "p"(arr)); |
3. 输入输出约束(读写)
| 约束 | 含义 | 示例 |
|---|---|---|
"+r" | 读写寄存器 | c int x=1; asm("incl %0" : "+r"(x)); |
"+m" | 读写内存 | c int x=1; asm("incl %0" : "+m"(x)); |
"+g" | 读写通用(寄存器/内存) | c int x=2; asm("addl $3, %0" : "+g"(x)); |
"0", "1" | 引用前面同编号操作数 | c int x=5; asm("addl %0, %0" : "+r"(x)); |
4. 特殊寄存器与组合
| 约束 | 含义 | 示例 |
|---|---|---|
"A" | eax+edx 组合(乘除法) | c long long res; int a=3,b=4; asm("imull %2" : "=A"(res) : "a"(a), "r"(b)); |
"q" | 特定寄存器子集 | c int x=7; asm("movl %0, %%eax" :: "q"(x)); |
"X" | 任意操作数 | c int x=9; asm("" :: "X"(x)); |
5. Clobber 特殊标记
| 标记 | 含义 | 示例 |
|---|---|---|
"cc" | 条件码寄存器 (EFLAGS) | c int a=1,b=2,c; asm("cmp %2,%1; setl %0" : "=r"(c) : "r"(a),"r"(b) : "cc"); |
"memory" | 表示内存被改动 | c int *p; asm volatile("" ::: "memory"); |
"~{flags}" | 标志寄存器 | c asm volatile("add $1, %%eax" ::: "~{flags}"); |
"~{dirflag}" | 方向标志 DF | 内存串操作前恢复 DF |
"~{fpsr}" | 浮点状态寄存器 | 浮点计算时声明破坏 |
uint32_t vlen = 64;
asm volatile(
"vsetvli zero,%[len],e32,m1,ta,ma;"
:: [len]"r"(vlen)
); -
"[len]"→ 操作数的名字,在汇编模板里你用%[len]来引用。 -
"r"(vlen)→ 约束 + C 变量:意思是“把 C 变量vlen的值放到一个寄存器里,然后在汇编里当作%[len]来用”。