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寄存器将被修改。