首页 > 代码库 > ATT汇编简介

ATT汇编简介


前言:汇编语言,对下取决于体系结构;对上取决于汇编器。在linux下,GCC编译出来的汇编默认为ATT语法的汇编,本文主要介绍ATT汇编:操作数长度、立即数表示方法,寄存器引用,操作数顺序,符号常量,内存引用等。


1,操作数的长度


         操作数的长度用加在指令后的符号表示 b(byte, 8-bit), w(word, 16-bits), l(long, 32-bits),如“movb %al, %bl”,“movw %ax, %bx”,“movl %eax, %ebx ”。

        如果没有指定操作数长度的话,编译器将按照目标操作数的长度来设置。比如指令 “mov %ax, %bx”,由于目标操作数 bx 的长度为 word,那么编译器将把此指令等同于“ movw %ax, %bx”。同样道理,指令“mov $4, %ebx”等同于指令“movl $4, %ebx”,“push%al” 等同于“pushb %al”。对于没有指定操作数长度,但编译器又无法猜测的指令,编译器将会报错,比如指令“push $4“


2. 立即数


使用立即数,要在数前面加符号$, 如“movl $0x04, %ebx”或者:
para = 0x04
movl $para, %ebx

3.寄存器引用


引用寄存器要在寄存器号前加百分号%,如“movl %eax, %ebx”。
80386 有如下寄存器:8 个 32-bit 寄存器 %eax,%ebx,%ecx,%edx,%edi,%esi,%ebp,%esp;
8 个 16-bit 寄存器,它们事实上是上面 8 个 32-bit 寄存器的低 16 位:%ax,%bx,%cx,%dx,%di,%si,%bp,%sp;
8 个 8-bit 寄存器:%ah,%al,%bh,%bl,%ch,%cl,%dh,%dl。它们事实上是寄存器%ax,%bx,%cx,%dx 的高 8 位和低 8 位;
6 个段寄存器:%cs(code),%ds(data),%ss(stack), %es,%fs,%gs;
3 个控制寄存器:%cr0,%cr2,%cr3;
6 个 debug 寄存器:%db0,%db1,%db2,%db3,%db6,%db7;
2 个测试寄存器:%tr6,%tr7;
8 个浮点寄存器栈:%st(0),%st(1),%st(2),%st(3),%st(4),%st(5),%st(6),%st(7).


4. 操作数顺序


操作数排列是从源(左)到目的(右),如“movl %eax(源), %ebx(目的)”


5, 符号常数


符号常数直接引用 如value: .long 0x12a3f2de
movl value , %ebx
指令执行的结果是将常数 0x12a3f2de 装入寄存器 ebx。
引用符号地址在符号前加符号$, 如“movl $value, % ebx”则是将符号 value 的地址装入寄存器 ebx。


6. 内存引用


Intel 语法的间接内存引用的格式为:section:[base+index*scale+displacement]

而在 AT&T 语法中对应的形式为:section:displacement(base,index,scale)


其 中 , base 和 index 是 任 意 的 32-bit base 和 index 寄 存 器 。 scale 可 以 取 值1,2,4,8。如果不指定 scale 值,则默认值为 1。section 可以指定任意的段寄存器作为段前 缀,默认的段寄存器在不同的情况下不一样。如果你在指令中指定了默认的段前缀则编译器在目标代码中不会产生此段前缀代码。下面是一些例子:
-4(%ebp) : base=%ebp , displacement=-4 , section 没 有 指 定 , 由 于 base=%ebp,所以默认的 section=%ss,index,scale 没有指定,则 index 为 0。
foo(,%eax,4):index=%eax,scale=4,displacement=foo。其它域没有指定。这里默认的 section=%ds。foo(,1):这个表达式引用的是指针 foo 指向的地址所存放的值。注意这个表达式中没有base 和 index,并且只有一个逗号,这是一种异常语法,但却合法。%gs:foo:这个表达式引用的是放置于%gs 段里变量 foo 的值。如果 call 和 jump 操作在操作数前指定前缀“ *”,则表示是一个绝对地址调用/跳转,也就是说 jmp/call 指令指定的是一个绝对地址。如果没有指定"*",则操作数是一个相对地址。任何指令如果其操作数是一个内存操作,则指令必须指定它的操作尺寸(byte,word,long),也就是说必须带有指令后缀(b,w,l)。