GCC 内联汇编 | 天一阁

GCC 内联汇编

GCC 内联汇编

GCC内联汇编就是可以在c代码里面加入汇编指令。有部分CPU指令是在C语言中没有提供对应功能的,比如lgdt, lidt等等。这些指令需要通过使用汇编直接操作CPU。在操作系统内核的代码中,这类汇编代码段非常常见,需要学习一下基本语法才能看懂OS内核代码的含义。

AT&T主要区别

  1. 操作数是源地址在前,目的地址在后的顺序in AT&T syntax the first operand is the source and the second operand is the destination
1
2
3
"Op-code dst src" in Intel syntax changes to
"Op-code src dst" in AT&T syntax.
  1. 寄存器名称前面需要加%

  2. 立即数用$开头

  3. 命令后缀’b’,‘w’,‘l’, 表示要操作的内存大小。byte(8-bit), word(16-bit), and long(32-bit)

  4. 内存寻址:

    section:disp(base, index, scale) in AT&T. section:[base + index*scale + disp]

    1
    2
    asm("movl %ecx %eax"); /* 把ecx的数据移动到eax */
    __asm__("movb %bh (%eax)"); /*把bh的一个字节放到eax所指的内存单元中,moves the byte from bh to the memory pointed by eax */

基本语法

1
asm("assembly code");

例子:

1
2
3
4
__asm__ ("movl %eax, %ebx\n\t"
"movl $56, %esi\n\t"
"movl %ecx, $label(%edx,%ebx,$4)\n\t"
"movb %ah, (%ebx)");

扩展语法

1
2
3
4
5
asm ( assembler template
: output operands /* optional */
: input operands /* optional */
: list of clobbered registers /* optional */
);

例子

1
2
3
4
5
6
7
asm("cld\n\t"
"rep\n\t"
"stosl"
: /* no output registers */
: "c" (count), "a" (fill_value), "D" (dest)
: "%ecx", "%edi"
);

例子2

1
2
3
4
5
6
7
int a=10, b;
asm ( "movl %1, %%eax;
movl %%eax, %0;"
:"=r"(b) /* output */
:"r"(a) /* input */
:"%eax" /* clobbered register */
);

说明:

  • “b” is the output operand, referred to by %0 and “a” is the input operand, referred to by %1.
  • “r” is a constraint on the operands. We’ll see constraints in detail later. For the time being, “r” says to GCC to use any register for storing the operands. output operand constraint should have a constraint modifier “=”. And this modifier says that it is the output operand and is write-only.
  • There are two %’s prefixed to the register name. This helps GCC to distinguish between the operands and registers. operands have a single % as prefix.
  • The clobbered register %eax after the third colon tells GCC that the value of %eax is to be modified inside “asm”, so GCC won’t use this register to store any other value.

参考文档 GCC Inline Assembly