数据格式
由于是由 16 位体系结构扩展成 32 位的,Intel 使用术语“字(word)”表示 16 位数据类型。因此,我们称 32 位为“双字(double words)”,称 64 位数为“四字(quad words)”。下表给出了 C 语言基本数据类型对应的 x86-64 表示。标准 int 值存储为双字(32 位)。指针(在此使用 char * 表示)存储为 8 字节的四字,64 位机器本来就预期如此。x86-64 中,数据类型 long 实现为 64 位,允许表示的值范围较大。x86-64 指令集同样包含完整的针对字节、字和双字的指令。
| C 声明 | Intel 数据类型 | 汇编代码后缀 | 大小(字节) |
|---|---|---|---|
| char | 字节 | b | 1 |
| short | 字 | w | 2 |
| int | 双字 | l | 4 |
| long | 四字 | q | 8 |
| char * | 四字 | q | 4 |
| float | 单精度 | s | 4 |
| double | 双精度 | l | 8 |
浮点数有两种形式:单精度、双精度。历史上还有过 80 位的浮点格式全套运算。在 C 语言中可以使用 long double 来进行声明。不过实现的硬件不如单双精度运算的高效。
访问信息
一个 x86-64 的中央处理单元(CPU)包含一组 16 个存储 64 位值的通用目的寄存器。它们用来存储整数数据和指针。下图显示了这些寄存器:
操作数指示符
大多数指令有一个或多个操作数(operand),指示出执行一个操作中要使用的源数据值,以及放置结果的目的位置。x86-64 支持多种操作数格式,如 表-2 所示。源数据值可以以常数形式给出,或是从寄存器或内存中读出。结果可以存放在集群其或内存中。因此各种不同的操作数可能性分为三种:
- 立即数(immediate):用来表示常数值。在 ATT 格式的汇编代码中,立即数的书写方式是‘\$’后跟一个用标准 C 表示法表示的整数。例如\$-577 或 \$0x1F。不同的指令允许的立即数范围不同,汇编器会自动选择最紧凑的方式进行数值编码。
- 寄存器(register):它表示某个寄存器的内容,16 个寄存器的低位 1 字节、2 字节、4 字节或 8 字节中的一个作为操作数,这些字节数分别对应 8 位、16 位、32 位或 64 位。在 表-2 中,我们用符号 $r_a$ 来表示任意寄存器 $a$,用引用 $R[r_a]$ 来表示它的值,这是将寄存器集合看作一个数组 $R$,用寄存器标识符作为索引。
- 内存引用:它根据计算出来的地址(常称作有效地址)访问某个内存位置。因为将内存看成一个很大的字节数组,我们用符号 $M_b[Addr]$ 表示对存储在内存中从 $Addr$ 开始的 $b$ 个字节值的引用。为了简便,我们通常省去下标 $b$,
如下表唆使,有多种不同的寻址方式,允许不同形式的内存引用。表中底部用语法 $I_{mm}(r_b,r_i,s)$ 表示的是最常用的形式。这样的引用有四个组成部分:
- 立即数偏移 $I_{mm}$
- 基址寄存器 $r_b$
- 变址寄存器 $r_i$
- 比例因子 $s$,$s\in\lbrace 1,2,4,8 \rbrace$
基址和变址寄存器必须是 64 位的寄存器。有效地址被计算为 $I_{mm}+R[r_b]+R[r_i]·s$。引用数组元素时,会用到这种通用形式。其他形式都是这种形式的特殊情况,只是省略了某些部分。正如我们所见,引用数组和结构元素时,比较复杂的寻址模式是很有用的。
| 类型 | 格式 | 操作数值 | 名称 |
|---|---|---|---|
| 立即数 | $\$I_{mm}$ | $I_{mm}$ | 立即数寻址 |
| 寄存器 | $r_a$ | $R[r_a]$ | 寄存器寻址 |
| 存储器 | $I_{mm}$ | $M[I_{mm}]$ | 绝对寻址 |
| 存储器 | $(r_a)$ | $M[R[r_a]]$ | 间接寻址 |
| 存储器 | $I_{mm}(r_b)$ | $M[I_{mm}+R[r_b]]$ | (基址+偏移量)寻址 |
| 存储器 | $(r_b,r_i)$ | $M[R[r_b]+R[r_i]]$ | 变址寻址 |
| 存储器 | $I_{mm}(r_b,r_i)$ | $M[I_{mm}+R[r_b]+R[r_i]]$ | 变址寻址 |
| 存储器 | $(,r_i,s)$ | $M[R[r_i]·s]$ | 比例变址寻址 |
| 存储器 | $I_{mm}(,r_i,s)$ | $M[I_{mm}+R[r_i]·s]$ | 比例变址寻址 |
| 存储器 | $(r_b,r_i,s)$ | $M[R[r_b]+R[r_i]·s]$ | 比例变址寻址 |
| 存储器 | $I_{mm}(r_b,r_i,s)$ | $M[I_{mm}+R[r_b]+R[r_i]·s]$ | 比例变址寻址 |
