https://www.cnblogs.com/kongj/p/14031770.html

https://gcc.gnu.org/onlinedocs/gcc-10.2.0/gcc/Using-Assembly-Language-with-C.html#Using-Assembly-Language-with-C

asm asm-qualifiers ( AssemblerTemplate 
                 : OutputOperands 
                 [ : InputOperands
                 [ : Clobbers ] ])

asm asm-qualifiers ( AssemblerTemplate 
                      : 
                      : InputOperands
                      : Clobbers
                      : GotoLabels)

OutputOperands 表示输出变量,InputOperands 表示输入变量,Clobbers 表示副作用(asm 块中可能修改的寄存器、内存)等

%n 代表第 n 个输入/输出

AT&T 语法中寄存器要加 % 前缀,因此 % 需要被跳脱。拓展内联汇编中,% 要写成 rax

%= 生成在所有 asm 块中唯一的数字,这个功能用于生成不重复的 local label 供跳转指令使用

  • r: 通用寄存器
  • i: 在汇编时或运行时可以确定的立即数
  • n: 可以直接确定的立即数,如整形字面量
  • g: 任意通用寄存器、内存、立即数
// 测试 val 的第 bit 位是否为 1
int 
bittest(unsigned long long val, unsigned long long bit)
{
    int ret;
    __asm__ (
        "movl $0, %0 \n\t"   // %0 代表 ret(第 0 个输入/输出)
        "btq %2, %1 \n\t"   // %1 代表 val(第 1 个输入/输出),%2 代表 bit。btq 指令将 val 的第 bit 位存入 CF 中
        "jnc %=f \n\t"              // 若 CF 标记为 1,将 ret 设置为 1
        "movl $1, %0 \n\t"
        "%=: movl $0, %0 \n\t"
        : "=&rm" (ret)   // ret 为输出变量。该变量可以被分配到通用寄存器或内存中中。不允许该输出变量与输入重叠。
        : "r" (val), "r" (bit)      // val 和 bit 是输入变量,分配到任意通用寄存器中
        : "cc", "memory"            // asm 块可能读取、修改条件寄存器和内存
            );
    return ret;
}