1 minute read

GCC 内联汇编

语法

asm (
assembler template // 汇编代码
:output operands   // 输出数 optional
:input operands    // 输入数 optional
:list of clobbered registers   // 被污染的寄存器 optional
)

下面是一个例子, 来自 pintos

// this pass the ip address of the eip to the eax, and jump to page_fault_handler

// then the err handler change eax, and jump back to this code, therefore return -1

/* Reads a byte at user virtual address UADDR.
   UADDR must be below PHYS_BASE.
   Returns the byte value if successful,
   -1 if a segfault occurred. */
static int get_user (const uint8_t *uaddr) {
    int result;
    asm ("movl $1f, %0; movzbl %1, %0; 1:"
    : "=&a" (result) : "m" (*uaddr));
    return result;
}

/* Writes BYTE to user address UDST.
   UDST must be below PHYS_BASE.
   Returns true if successful,
   false if a segfault occurred. */
static bool put_user (uint8_t *udst, uint8_t byte) {
    int error_code;
    asm ("movl $1f, %0; movb %b2, %1; 1:"
    : "=&a" (error_code), "=m" (*udst) : "q" (byte));
    return error_code != -1;
}
  • “$1f”为向前引用”1:”处的地址

  • 第一项为汇编代码, 多条语句用 ; 分割
  • 第二项为输出操作数, 以”=?”形式, (constraints 约束)
  • 第三项为输入操作数, 以”?”形式
  • 第四项标出汇编代码中被修改的寄存器, 或者用”memory”表示修改了内存, 需要更新某些寄存器值

  • 操作数(包括输入输出), 从 0 开始, 依次排序, 以(%+数字)显示在汇编代码中
  • 操作数”?”可以包括一下标识符
    1. a,b,c,d,S,D -> eax,ebx,ecx,edx,esi,edi
    2. r 上述任意寄存器
    3. m 内存
    4. i 立即数
    5. g 寄存器,内存,立即数均可
  • 与特殊架构相关的一些格式, 以下为i386独有
    1. constraints “q” Any register accessible as rl. In 32-bit mode, a, b, c, and d; in 64-bit mode, any integer register.
    2. “%b2” -> “%al”, “%h0” -> “%ah”
  • 如果你不想你写的汇编语句被优化, 那就在 asm 关键字后加上 volatile 关键字

  • 约束修饰字符
    1. (“=”: write-only)
    2. (“+”: read-write)
    3. (“&”: eary-clobber 操作数, 在指令使用输入操作数之前被写入了值, 所以这个操作数就不能位于输入操作数的寄存器, 以免被覆盖

代码示例

int a = 10, b = 2, c = 10;
asm (
  "movl %1, %%eax;"
  "addl %2, %%eax;"
  "movl %%eax, %0"
  : "=r"(c)
  : "r"(a), "r"(b)
  : "%eax"
);

int five_times_x = 4; int x = 10;
asm ("leal (%0,%0,4), %0"
     : "=r" (five_times_x)
     : "0" (x) // 即是输入也是输出
     );

Tags:

Categories:

Updated: