3.2 程序编码
3.2.1 机器级代码
- 程序计数器(PC,在x86-64中用%rip表示):给出要执行的下一条指令在内存中的地址
- 整数寄存器:包含16个命名位置,分别存储64位值。可以存储地址或整数。有的寄存器用来记录程序状态,其他的保存临时数据
- 条件码寄存器:保存最近执行的算术或逻辑指令状态。用来实现控制或数据流中的条件变化
- 一组向量寄存器可以存放一个或多个整数或浮点数
- 程序内存(虚拟地址寻址):
- 程序的可执行机器代码
- 操作系统需要的信息
- 用来管理过程调用和返回的运行时栈
- 用户分配的内存块
3.2.2 代码示例
- 机器代码和它的反汇编表示的特性
- x86-64指令长度1-15字节不等。常用指令及操作数较少的指令所需字节数少
- 设计指令格式的方式:从某个给定位置开始,可以将字节唯一地解码成机器指令
3.3 数据格式
C声明 | Intel数据类型 | 汇编代码后缀 | 大小(字节) |
---|
char | 字节 | b | 1 |
short | 字(word) | w | 2 |
int | 双字(long word) | l | 4 |
long | 四字(quad words) | q | 8 |
char- | 四字 | q | 8 |
float | 单精度 | s | 4 |
double | 双精度 | l | 8 |
3.4 访问信息
3.4.1 操作数指示符
- 立即数(immediate):
- 寄存器(register):
- 内存引用
- 语法:$Imm(r_b,r_i,s)$
- Imm:立即数偏移
- $r_b$:基址寄存器
- $r_i$:变址寄存器
- s:比例因子,必须是1、2、4、8
- 操作数值:$M[Imm+R[r_b]+R[r_i]·s]$
3.4.2 数据传送指令
- 两个操作数不能都指向内存$Imm(r_b,r_i,s)$位置
- 后缀大小与内存部分无关
- MOV(S,D):
- S(源):立即数,存储在寄存器/内存
- D(目的位置):寄存器/内存地址
- movl(S——>寄存器):把该寄存器的高位4字节设置为0
- movabsq(绝对):(S(64位)——>D(寄存器))
- MOVZ(S(小),R(大)):R<——零扩展(S)
- MOVS(S(小),R(大)):R<——符号扩展(S)
3.4.4 压入和弹出栈数据
- pushq:入栈,指针-8
- popq:出栈,指针+8
3.5 算术和逻辑操作
指令 | 效果 | 描述 |
---|
leaq S,D | D <—— &S | 加载有效地址 |
INC D | D <—— D+1 | 加1 |
DEC D | D <—— D-1 | 减l |
NEG D | D <—— -D | 取负 |
NOT D | D <—— ~D | 取补 |
ADD S,D | D <—— D+S | 加 |
SUB S,D | D <—— D-S | 减 |
IMUL S,D | D <—— D*S | 乘 |
XOR S,D | D <—— D^S | 异或 |
OR S,D | D <—— D|S | 或 |
AND S,D | D <—— D&S | 与 |
SAL K,D | D <—— D«K | 左移 |
SHL K,D | D <—— D«K | 左移(等同于SAL) |
SAR K,D | D <—— D»$_A$K | 算术右移 |
SHR K,D | D <—— D»$_L$K | 逻辑右移 |
3.5.1 加载有效地址
leaq(load effective address),movq的变形
3.5.5 特殊的算术操作
指令 | 效果 | 描述 |
---|
imulq S | R[%rdx]:R[%rax]<——S*R[%rax] | 有符号全乘法 |
mulq S | R[%rdx]:R[%rax]<——S*R[%rax] | 无符号全乘法 |
clto | R[%rdx]:R[%rax]<——符号扩展(R[%rax]) | 转换为八字 |
idivq S | R[%rdx]<——R[%rdx]:R[%rax] mod/÷ S | 有符号除法 |
divq S | R[%rdx]<——R[%rdx]:R[%rax] mod/÷ S | 无符号除法 |
文章作者
lim
上次更新
2024-11-21
(1dac9ff)
许可协议
CC BY-NC-ND 4.0