AT&T(内联)汇编语言使用

1. 第一个 operand为 source, 第二个为 destination (和 Intel刚好相反).

movl    %eax, %ebx 
把EAX的内容复制到  EBX

2. 寄存器名字:

寄存器名字前加前缀%.

3. 立即数名字前面加  $. 静态的C语言变量名字前面也要加 $.

4. operand 的大小通过operator的最后一个字符(b,w,l)确定。

5.内存操作:

AT&T: section:disp(base, index, scale)

Intel: section:[base + index*scale + disp]

对于用作 disp/scale 的常量,不用加前缀 $

movl $bar, %eax ----> 把 变量bar的地址保存到  EAX

movl bar, %eax ----> 把变量 bar的内容保存到 EAX

变量前不加前缀表示它是一个内存地址

+------------------------------+------------------------------------+
|       Intel Code             |      AT&T Code                     |
+------------------------------+------------------------------------+
| mov     eax,1                |  movl    $1,%eax                   |   
| mov     ebx,0ffh             |  movl    $0xff,%ebx                |   
| int     80h                  |  int     $0x80                     |   
| mov     ebx, eax             |  movl    %eax, %ebx                |
| mov     eax,[ecx]            |  movl    (%ecx),%eax               |
| mov     eax,[ebx+3]          |  movl    3(%ebx),%eax              | 
| mov     eax,[ebx+20h]        |  movl    0x20(%ebx),%eax           |
| add     eax,[ebx+ecx*2h]     |  addl    (%ebx,%ecx,0x2),%eax      |
| lea     eax,[ebx+ecx]        |  leal    (%ebx,%ecx),%eax          |
| sub     eax,[ebx+ecx*4h-20h] |  subl    -0x20(%ebx,%ecx,0x4),%eax |
+------------------------------+------------------------------------+

6 Basic inline

如下:

asm("assembly code");

asm也可以写成 __asm__

如果是多个 汇编指令,可以写成多行的形式,每行以 \n \t结尾:

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

7. Extended assembly

可以指定 输出寄存器,输入寄存器和 clobbered的寄存器

       asm ( assembler template 
           : output operands                  /* optional */
           : input operands                   /* optional */
           : list of clobbered registers      /* optional */
           );
assembler template 由汇编指令组成。每个  operand 由一个operand-constriant 的字符串和后面紧接的在括号内的C语言表达式组成。

冒号把汇编指令和operand分割开。

        int a=10, b;
        asm ("movl %1, %%eax; 
              movl %%eax, %0;"
             :"=r"(b)        /* output */
             :"r"(a)         /* input */
             :"%eax"         /* clobbered register */
             ); 
数字0表示输出 operator (b), 1 表示输入 operator (a). 输出操作数前面要有 "=",表示这个操作数是 write-only. r表GCC可以使用任何寄存器保存操作数。

寄存器名字前面有两个 % 以便 GCC 能区分寄存器和操作数。操作数有一个前缀 %.

在 clobbered register list里的  %eax表示 EAX寄存器将被修改。


你可能感兴趣的:(AT&T(内联)汇编语言使用)