Intel用术语“字(word)”表示16位数据类型。称32位数为“双字”
C声明 Intel数据类型 汇编代码后缀 大小(字节)
char 字节 b 1
short 字 w 2
int 双字 l 4
long 四字 q 8
char* 四字 q 8
float 单精度 s 4
double 双精度 l 8
-----------------------------------------------------------------------------------------------
简单数据传送指令
指令 效果 描述
(源操作数指定的值是一个立即数、存储在寄存器中或者内存中,目的操作数指定一个位置,要么是寄存器,要么是内存地址。
x86-64加了一条限制,传送指令的两个操作数不能都指向内存位置)
MOV S, D D <-- S 传送
movb 传送字节
movw 传送字
movl 传送双字
movq (只能以表示为32位补码数字的立即数作为源操作数) 传送四字
movabsq I, R(只能用寄存器作目标) R <-- I 传送绝对的四字
-----------------------------------------------------------------------------------------------
零扩展数据传送指令
(以寄存器或内存地址作为源,以寄存器作为目的)
指令 效果 描述
MOVZ S, R R <-- 零扩展(S) 以零扩展进行传送
movzbw 零扩展的字节传送到字
movzbl 零扩展的字节传送到双字
movzwl 零扩展的字传送到双字
movzbq 零扩展的字节传送到四字
movzwq 零扩展的字传送到四字
-----------------------------------------------------------------------------------------------
符号扩展数据传送指令
(以寄存器或内存地址作为源,以寄存器作为目的,cltq指令只能作用于寄存器%eax和%rax)
指令 效果 描述
MOVS S, R R <-- 符号扩展(S) 以符号扩展进行传送
movsbw 符号扩展的字节传送到字
movsbl 符号扩展的字节传送到双字
movswl 符号扩展的字传送到双字
movsbq 符号扩展的字节传送到四字
movswq 符号扩展的字传送到四字
movslq 符号扩展的双字传送到四字
cltq %rax <-- 符号扩展(%eax) 把%eax符号扩展到%rax
-----------------------------------------------------------------------------------------------
入栈和出栈指令
(以寄存器或内存地址作为源,以寄存器作为目的,cltq指令只能作用于寄存器%eax和%rax)
指令 效果 描述
pushq S 将四字压入栈
popq D 将四字弹出栈
-----------------------------------------------------------------------------------------------
算术和逻辑操作
指令 效果 描述
leaq S,D D <-- &S 加载有效地址
INC D D <-- D+1 加1
DEC D D <-- D-1 减1
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 逻辑右移
-----------------------------------------------------------------------------------------------
特殊的算术操作
指令 效果 描述
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 有符号除法
R[%rdx] <-- R[%rdx]: R[%rax] / S
divq S R[%rdx] <-- R[%rdx]: R[%rax] mod S 无符号除法
R[%rdx] <-- R[%rdx]: R[%rax] / S
-----------------------------------------------------------------------------------------------
条件码
CF:进位标志。最近的操作使最高位产生了进位。可用来检查无符号操作的溢出
ZF:零标志。最近的操作得出的结果为0
SF:符号标志。最近的操作得到的结果为负数
OF:溢出标志。最近的操作导致一个补码溢出————正溢出和负溢出
-----------------------------------------------------------------------------------------------
比较和测试指令,这些指令不修改任何寄存器的值,只设置条件码
指令 基于 描述
CMP S1,S2 S2 - S1 比较
cmpb 比较字节
cmpw 比较字
cmpl 比较双字
cmpq 比较四字
TEST S1,S2 S1 & S2 测试
testb 测试字节
testw 测试字
testl 测试双字
testq 测试四字
-----------------------------------------------------------------------------------------------
SET指令。每条指令根据条件码的某种组合,将一个字节设置为0或者1
指令 同义名 效果 设置条件
sete D setz D <-- ZF 相等/零
setne D setnz D <-- ~ZF 不等/非零
sets D D <-- SF 负数
setns D D <-- ~SF 非负数
setg D setnle D <-- ~(SF^OF) & ~ZF 大于(有符号>)
setge D setnl D <-- ~(SF^OF) 大于等于(有符号>=)
setl D setnge D <-- SF^OF 小于(有符号<)
setle D setng D <-- (SF^OF) | ZF 小与等于(有符号<=)
seta D setnbe D <-- ~CF & ~ZF 超过(无符号>)
setae D setnb D <-- ~CF 超过或相等(无符号>=)
setb D setnae D <-- CF 低于(无符号<)
setbe D setna D <-- CF | ZF 低于或相等(无符号<=)
-----------------------------------------------------------------------------------------------
jump指令。当跳转条件满足时,这些指令会跳转到一条带标号的目的地。
指令 同义名 跳转条件 描述
jmp Label 1 直接跳转
jmp *Operand 1 间接跳转
je Label jz ZF 相等/零
jne Label jnz ~ZF 不相等/非零
js Label SF 负数
jns Label ~SF 非负数
jg Label jnle ~(SF^OF) & ~ZF 大于(有符号>)
jge Label jnl ~(SF^OF) 大于或等于(有符号>=)
jl Label jnge SF^OF 小于(有符号<)
jle Label jng (SF^OF) | ZF 小于或等于(有符号<=)
ja Label jnbe ~CF & ~ZF 超过(无符号>)
jae Label jnb ~CF 超过或相等(无符号>=)
jb Label jnae CF 低于于(无符号<)
jbe Label jna CF | ZF 低于或相等(无符号<=)
-----------------------------------------------------------------------------------------------
条件传送指令。当传送条件满足时,指令把源值S复制到目的R。
源地址可以时寄存器或者内存地址,目的地址只能是寄存器
源和目的的值可以是16位、32位或64位。不支持单字节的条件传送
指令 同义名 传送条件 描述
cmove S,R cmovz ZF 相等/零
cmovne S,R cmovnz ~ZF 不相等/非零
cmovs S,R SF 负数
cmovns S,R ~SF 非负数
cmovg S,R cmovnle ~(SF^OF)&~ZF 大于(有符号>)
cmovge S,R cmovnl ~(SF^OF) 大于或等于(有符号>=)
cmovl S,R cmovnge SF^OF 小于(有符号<)
cmovle S,R cmovng (SF^OF)|ZF 小于或等于(有符号<=)
cmova S,R cmovnbe ~CF & ~ZF 超过(无符号>)
cmovae S,R cmovnb ~CF 超过或相等(无符号>=)
cmovb S,R cmovnae CF 低于(无符号<)
cmovbe S,R cmovna CF | ZF 低于或相等(无符号<=)
-----------------------------------------------------------------------------------------------
转移控制
指令 描述
call Label 过程调用
call *Operand 过程调用
ret 从过程调用中返回
寄存器使用规则
寄存器
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 被调用者保存
x86-64中,可以通过寄存器最多传递6个整型(例如整数和指针)参数。寄存器的使用是有特殊
顺序的,寄存器使用的名字取决于要传递的数据类型的大小。如果超出6个整型参数,超出的部
分通过栈传递
操作数大小 参数数量
1 2 3 4 5 6
64 %rdi %rsi %rdx %rcx %r8 %r9
32 %edi %esi %edx %ecx %r8d %r9d
16 %di %si %dx %cx %r8w %r9w
8 %dil %sil %dl %cl %r8b %r9b
确定分支预测错误的处罚
Tavg(p) = (1 - p)Tok + p(Tok + Tmp) = Tok + pTmp
Tran = Tavg(0.5) = Tok + 0.5Tmp Tmp = 2(Tran - Tok)
Tok:预测准确,执行代码的时间 Tmp:预测错误的处罚时间 Tavg:执行代码的平均时间 Tran:随机情况下,每次调用需要的周期 Tran = Tavg(0.5)
附录
2.3.7节内容;被除数是负数的话,必须加上偏移量 2^k - 1