前言
本篇文章介绍x86-64汇编指令支持的操作数格式
x86-64汇编指令支持的操作数格式主要分为三类
- 立即数
- 寄存器
- 内存引用
立即数
在ATT格式的汇编代码中,立即数的书写方式是$
后面跟一个用标准C表示法表示的整数,比如,$-577或$Ox1F
。不同的指令允许的立即数值范围不同,汇编器会自动选择最紧凑的方式进行数值编码。
寄存器
表示某个寄存器的内容,16个寄存器的低位1字节、2字节、4字节或8字节中的一个作为操作数,这些字节数分别对应于8位、16位、32位或64位。
使用%R
的格式来表示寄存器的值,R是寄存器的名称。
内存引用
内存引用其实表示的就是内存地址,只不过这个计算的地址是虚拟地址
,虚拟地址到物理地址的实际转换是操作系统做的事情,内存引用的情况很多,但是都是根据公式
I
m
m
(
R
b
,
R
i
,
s
)
Imm(R_b,R_i,s)
Imm(Rb,Ri,s)
来计算的,其中
I
m
m
Imm
Imm:一个常数,表示虚拟地址的偏移量
R
b
R_b
Rb:基址寄存器
R
i
R_i
Ri:变址寄存器
s
s
s:比例因子,
s
s
s的值只能是1,2,4,8
,并且默认值是1
最终的虚拟地址为:
a
d
d
=
I
m
m
+
R
b
的值
+
R
i
的值
×
s
add = Imm + R_b的值 + R_i的值 \times s
add=Imm+Rb的值+Ri的值×s
注意:如果公式中省略了s,则计算的时候
s
=
1
s=1
s=1
实例
%rax
:这是一个寄存器操作数,表示寄存器rax存储的值
$0x108
:这是一个立即数操作数
(%rax)
:这是一个内存引用,不过省略了常数偏移,变址寄存器,和比例因子,表示的是寄存器rax的值所指向的内存地址
4(%rax)
:这是一个内存引用,不过省略了变址寄存器,和比例因子,表示的是 (4 + 寄存器rax的值)所指向的内存地址
9(%rax,%rdx)
:这是一个内存引用,不过省略了比例因子,表示的是 (9 + 寄存器rax的值 + 寄存器rdx的值 * 1)所指向的内存地址
,虽然省略了比例因子,但是默认是1.
0XFC(,%rdx,4)
:这是一个内存引用,不过省略了基址寄存器,表示的是 (0XFC + 寄存器rdx的值 * 4)所指向的内存地址
(%rax,%rdx,4)
:这是一个内存引用,不过省略了常数偏移,表示的是 (寄存器rax的值 + 寄存器rdx的值 * 4)所指向的内存地址