寄存器
- x86-64结构的CPU包含一组16个存储64位值的通用目的寄存器;历史上最开始的寄存器只有8个8位的寄存器,后来经历了16位, 32位直至现在的64位,寄存器也由8个扩展到16个。
- 程序可以依据每个寄存器的名称使用其中的8位,或16位,或32位,或64位;使用每个寄存器有约定的使用目的。
下面以表格的形式给出寄存器的名称与用法
63 | 31 | 15 | 7 | 0 |
---|---|---|---|---|
%rax | %eax | %ax | %al | 返回值 |
%rbx | %ebx | %bx | %bl | 被调用者保存 |
%rcx | %ecx | %cx | %cl | 第4个参数 |
%rdx | %edx | %dx | %dl | 第3个参数 |
%rsi | %esi | %si | %sil | 第2个参数 |
%rdi | %edi | %di | %dil | 第1个参数 |
%rbp | %ebp | %bp | %bpl | 被调用者保存 |
%rsp | %esp | %sp | %spl | 栈指针 |
%r8 | %r8d | %r8w | %r8b | 第5个参数 |
%r9 | %r9d | %r9w | %r9b | 第6个参数 |
%r10 | %r10d | %r10w | %r10b | 调用者保存 |
%r11 | %r11d | %r11w | %r11b | 调用者保存 |
%r12 | %r12d | %r12w | %r12b | 被调用者保存 |
%r13 | %r13d | %r13w | %r13b | 被调用者保存 |
%r14 | %r14d | %r14w | %r14b | 被调用者保存 |
%r15 | %r15d | %r15w | %r15b | 被调用者保存 |
注:%rip是程序计数器,与这16个不同。
- 调用者保存是指当P函数调用Q函数时,该寄存器中的内容由调用者P负责保存,Q可以直接使用该寄存器。
- 被调用者保存是指当P函数调用Q函数时,该寄存器中的内容由被调用者Q负责保存,Q在使用这些寄存器前应当先把这些寄存器内的值存入栈中,Q返回之前应当将对应的值从栈中恢复到寄存器上。
数据类型
以下是64位结构上对应的数据类型。Intel用术语“字word”表示16位的数据类型;byte表示字节,long word表示32位,q表示64位
C声明 | Intel数据类型 | 汇编代码后缀 | 大小(字节) |
---|---|---|---|
char | 字节 | b | 1 |
short | 字 | w | 2 |
int | 双字 | l | 4 |
long | 四字 | q | 8 |
char * | 四字 | q | 8 |
float | 单精度 | s | 4 |
double | 双精度 | l | 8 |
cpu寻址
cpu操作数据就需要知道数据的地址,通过寻址来实现。寻址分为直接寻址和间接寻址。以下做一些解释。
操作数:
- 立即数 $标准C表示法表示的整数
- 寄存器 R[ra]
- 内存引用 Mb[Addr]
Imm(rb, ri, s): 有效地址 Imm+R[rb]+R[ri]*s; 注意两个rb,ri都必须是64位寄存器,比例因子s必须是1, 2, 4或8
类型 | 格式 | 操作数值 | 名称 |
---|---|---|---|
立即数 | $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, ri, s) | M[R[rb]+R[ri]*s] | 比例变址寻址 |
存储器 | Imm(rb, ri, s) | M[Imm+R[rb]+R[ri]*s] | 比例变址寻址 |
任何操作都不能直接进行内存到内存数据修改,要实现内存到内存的数据操作只能先将数据修改到寄存器,然后再通过寄存器修改到内存