3.2 程序编码

3.2.1 机器级代码

  • 程序计数器(PC,在x86-64中用%rip表示):给出要执行的下一条指令在内存中的地址
  • 整数寄存器:包含16个命名位置,分别存储64位值。可以存储地址或整数。有的寄存器用来记录程序状态,其他的保存临时数据
  • 条件码寄存器:保存最近执行的算术或逻辑指令状态。用来实现控制或数据流中的条件变化
  • 一组向量寄存器可以存放一个或多个整数或浮点数
  • 程序内存(虚拟地址寻址):
    • 程序的可执行机器代码
    • 操作系统需要的信息
    • 用来管理过程调用和返回的运行时栈
    • 用户分配的内存块

3.2.2 代码示例

  • 机器代码和它的反汇编表示的特性
    • x86-64指令长度1-15字节不等。常用指令及操作数较少的指令所需字节数少
    • 设计指令格式的方式:从某个给定位置开始,可以将字节唯一地解码成机器指令

3.3 数据格式

C声明Intel数据类型汇编代码后缀大小(字节)
char字节b1
short字(word)w2
int双字(long word)l4
long四字(quad words)q8
char-四字q8
float单精度s4
double双精度l8
  • 任何指针都是8字节

3.4 访问信息

3.4.1 操作数指示符

  • 立即数(immediate):
    • 语法:$Imm
    • 操作数值:Imm(常数)
  • 寄存器(register):
    • 语法:$r_a$
    • 操作数值:$R[r_a]$
  • 内存引用
    • 语法:$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)
    • cltq:只用于寄存器%eax和%rax

3.4.4 压入和弹出栈数据

  • pushq:入栈,指针-8
  • popq:出栈,指针+8

3.5 算术和逻辑操作

指令效果描述
leaq S,DD <—— &S加载有效地址
INC DD <—— D+1加1
DEC DD <—— D-1减l
NEG DD <—— -D取负
NOT DD <—— ~D取补
ADD S,DD <—— D+S
SUB S,DD <—— D-S
IMUL S,DD <—— D*S
XOR S,DD <—— D^S异或
OR S,DD <—— D|S
AND S,DD <—— D&S
SAL K,DD <—— D«K左移
SHL K,DD <—— D«K左移(等同于SAL)
SAR K,DD <—— D»$_A$K算术右移
SHR K,DD <—— D»$_L$K逻辑右移

3.5.1 加载有效地址

leaq(load effective address),movq的变形

  • 可以执行加法和有限乘法

3.5.5 特殊的算术操作

指令效果描述
imulq SR[%rdx]:R[%rax]<——S*R[%rax]有符号全乘法
mulq SR[%rdx]:R[%rax]<——S*R[%rax]无符号全乘法
cltoR[%rdx]:R[%rax]<——符号扩展(R[%rax])转换为八字
idivq SR[%rdx]<——R[%rdx]:R[%rax] mod/÷ S有符号除法
divq SR[%rdx]<——R[%rdx]:R[%rax] mod/÷ S无符号除法