ATT汇编语法简介

这里,我们介绍三种类型的ATT汇编指令操作数的表示方法,其中指令参考对应体系的指令集(ISA)。

 

第一种类型是立即数(immediate),其书写方式是'$'后面跟一个用标准C表示法表示的整数,比如$-577或$0x1F。任何能够放进一个64位字里的数值都可以用作立即数,不过汇编器在可能时会使用一个、两个、四个或八个字节的编码。

 

第二种类型是寄存器(register),其表示某个寄存器的内容,对四字操作来说,可以是16个64位寄存器中的一个(例如,%rax),对双字操作来说,可以是16个32位寄存器中的一个(例如,%eax),对于字或字节操作类同。我们用符号Ea来表示任意的寄存器a,用引用R[Ea]来表示它的值,这是将寄存器集合看成一个数组R,用寄存器标识符作为索引。

第三类操作数是存储器(memory)引用,其会根据计算出来的地址(通常是有效地址)访问某个存储器位置。因为将存储器看成一个很大的字节数据,我们用符号Mb[Addr]来表示存储在存储器中从地址Addr开始的b个字节值的引用。为了方便,我们省去下方的b。

 

寻址模式,其允许不同形式的存储器引用。语法Imm(Eb,Ei,s)表示的是最常用的形式。这样的引用有四个组成部分:一个立即数偏移Imm,一个基址寄存器Eb,一个变址寄存器Ei和一个比例因子s,这里的s必须是1、2、4或8(这个表达式也就是我们初中数学中学到的线性函数y=ax+b+C的ATT语法啦)。然后,有效地址被计算为Imm+R[Eb]+R[Ei]×s。引用数组元素时,会用到这种通用形式。其他形式都是这种通用形式的特殊情况,只是省略了某些部分。如下图:

 

类 型

格 式

操作数值

名 称

示 例

立即数

$Imm

Imm

立即数寻址

movq $0x1234,%rax

寄存器

Ea

R[Ea]

寄存器寻址

movq %rax,%rdx

存储器

Imm

M[Imm]

绝对寻址

movq 0x80064,%rbx

存储器

(Ea)

M[R[Ea]]

间接寻址

movq (%ebp),%esp

存储器

Imm(Eb)

M[Imm+R[Eb]]

(基址+偏移量)寻址

movq 0x8(%rdi),%rax

存储器

(Eb,Ei)

M[R[Eb]+R[Ei]]

变址寻址

movq (%rdi,%rax),%rcx

存储器

Imm(Eb,Ei)

M[Imm+R[Eb]+R[Ei]]

变址寻址

movq 0x8(%rdi,%rax),%rcx

存储器

(,Ei,s)

M[R[Ei]×s]

比例变址寻址

movq (,%rdi,0x2),%rcx

存储器

Imm(,Ei,s)

M[Imm+R[Ei]×s]

比例变址寻址

movq 0x8(,%rdi,0x2),%rcx

存储器

(Eb,Ei,s)

M[R[Eb]+R[Ei]×s]

比例变址寻址

movq (%rbx,%rdi,0x2),%rcx

存储器

Imm(Eb,Ei,s)

M[R[Eb]+R[Ei]×s]

比例变址寻址

movq 0x8(%rbx,%rdi,0x2),%rcx

 

GCC的开发者坚定地保持与i386的二进制兼容性,即使是IA32指令集中添加了有用的特性,包括条件传送和更现代的浮点指令集。只有以特殊的命令行选项设置编译时,才会使用这些特性。在x86-64作为目标时,这为GCC提供了一个放弃后向兼容性的机会,只用标准的命令行选项就能利用这些新特性。

 

对于x86-64位平台与IA32的主要特性区别是:

  1. 指针和长整型是64位长。整数算术运算支持8、16、32和64位数据类型;
  2. 通用目的寄存器组从8个扩展到16个,分别为%r[a-d]x,%r[sd]i,%r[bs]p,%r[8-15]。其中,%rbp不再专用为frame pointer,而是通用寄存器;
  3. 许多程序状态都保存在寄存器中,而不是栈上。整形和指针类型的过程参数(最多6个)通过寄存器传递。有些程序根本不需要访问栈;
  4. 如果可能,条件操作用条件传送指令实现,会得到比传统分支代码更好的性能;
  5. 浮点操作用面向寄存器的指令集(SSE2 or later)来实现,而不是x87。

 

posted @ 2012-07-13 17:48  chee z  阅读(3412)  评论(0编辑  收藏  举报