大多数指令有一个或者多个操作数,指示出执行一个操作中要使用的源数据值,以及放置结果的目的位置。x86-64支持多种操作数格式。
源数据值可以以常数形式给出,或者是从寄存器或内存中读出。
结果可以存放在寄存器或内存中。
立即数寻址
在AT&T汇编中,立即数用来表示常数值。立即数的书写方式是$后面跟随一个用标准C表示法表示的整数。
不同的指令允许的立即数值范围不同,汇编器会自动选择最紧凑的方式进行数值编码。
寄存器寻址
寄存器寻址主要是根据寄存器的名称读取寄存器的内容。
16个寄存器的低位1字节、2字节、4字节、8字节中的一个作为操作数,这些字节数分别对应于8位、16位、32位、24位。
我们用符号ra来表示任意寄存器a,用R[ra]来表示它的值,这是将寄存器集合看成一个数组R,用寄存器标识符作为索引。
内存寻址
内存寻址会根据计算出来的有效地址,访问某个内存位置。
因为将内存看成一个很大的字节数组,我们用Mb[Addr]表示对存储在内存中从地址Addr开始的b个字节值的引用。为了简便,我们通常省去下标b。
针对不同的寻址模式,总结如下表:
类型 |
格式 |
操作数值 |
名称 |
立即数 |
$Imm |
Imm |
立即数寻址 |
寄存器 |
ra |
R[ra] |
寄存器寻址 |
存储器 |
Imm |
M[Imm] |
绝对寻址 |
存储器 |
(ra) |
M[R[ra]] |
间接寻址 |
存储器 |
Imm(rb) |
M[Imm+R[rb]] |
(基址+偏移量)寻址 |
存储器 |
(rb,ri) |
M[R[rb]+R[ri]] |
变址寻址 |
存储器 |
Imm(rb,ri) |
M[Imm+R[rb]+R[ri]] |
变址寻址 |
存储器 |
(,ri,s) |
M[R[ri]∗s] |
比例变址寻址 |
存储器 |
Imm(,ri,s) |
M[Imm+R[ri]∗s] |
比例变址寻址 |
存储器 |
(rb,rs,i) |
M[R[rb]+R[ri]∗s] |
比例变址寻址 |
存储器 |
Imm(rb,ri,s) |
M[Imm+R[rb]+R[ri]∗s] |
比例变址寻址 |
对于寻址语法Imm(rb,ri,s),表示的是最常用的形式。
这样的引用由4部分组成,一个立即数偏移Imm,一个基址寄存器rb,
一个变址寄存器ri和一个比例因子s,这里s必须是1、2、4或者8.
基址和变址寄存器都必须是64位寄存器。
有效地址被计算为Imm+R[rb]+R[ri]∗i。
引用数组元素时,会用到这种通用形式。
其他形式都是这种通用形式的特殊情况,只是省略了某些部分。