BLOG

Record, summarize, and improve.

内联汇编

内联汇编约束 + 示例代码速查表

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] 来用”。