x64 常用指令
😄
1 常用指令
mul、div
这部分后续专门学习硬编码(Intel 手册卷2)。如下 mul 指令为无符号乘法。

r - 通用寄存器
m - 内存
imm - 立即数
r8 - 8位通用寄存器
m8 - 8位内存
imm8 - 8位立即数
mul 指令:执行第一个操作数(目标操作数)和第二个操作数(源操作数)的无符号乘法,并将结果存储在目标操作数中。 目标操作数是位于寄存器 AL、AX 或 EAX 中的隐含操作数(取决于操作数的大小); 源操作数位于通用寄存器或内存位置。 该指令的动作和结果的位置取决于操作码和操作数大小,如表 3-69 所示(Operand操作数)。

如下为计算过程:


shl、shr、sal、sar、rol、ror、rcl、rcr
| 指令 | 指令格式 | 解释 |
|---|---|---|
| shl | SHL r/m, r/imm | 逻辑左移。低位补0。对于 x64 来说,将最高位 Bit 63 置入 CF。 |
| sal | SAL r/m, r/imm | 算术左移。等价于逻辑左移。低位补0。对于 x64 来说,将最高位 Bit 63 置入 CF。![]() |
| shr | SHR r/m, r/imm | 逻辑右移。高位补0。对于 x64 来说,将最低位 Bit 0 置入 CF。 |
| sar | SAR r/m, r/imm | 算术右移。高位补符号位。对于 x64 来说,将最低位 Bit 0 置入 CF。![]() |
| rcl | RCL r/m, r/imm | 带进位循环左移。将 CF 当作 bit 64,然后从 CF 开始移位补到低位去(CF 是扩展位,此时操作数相当于是共65位)。intel 卷1 Chapter 7。 |
| rcr | RCR r/m, r/imm | 带进位循环右移。将 CF 当作 bit -1,然后从 CF 开始移位补到高位去(CF 是扩展位,此时操作数相当于是共65位)。 |
| rol | ROL r/m, r/imm | 不带进位循环左移。与 RCL 区别就是,每个移出的最高位都会经过 CF,但是 CF 不作为扩展位。 |
| ror | ROR r/m, r/imm | 不带进位循环右移。与 RCR 区别就是,每个移出的最低位都会经过 CF,但是 CF 不作为扩展位。注意下下面 ROR 移出的位并不会通过 CF 来循环。![]() |
SHL、SHR:用于无符号乘法(MUL)、无符号除法(DIV)。
SAL、SAR:用于有符号乘法(MUL)、有符号除法(IDIV)。
movsx、movsz
符号扩展与零扩展指令。这两个指令用来将一个数的宽度进行扩展。如一个数为 4 字节,可以扩展为 8 字节。
指令格式:movsx/movzx dest, src。
movsx:将dest高位全部填充为src的符号位。movzx:将dest高位全部填充为0。
pushad、popad
pushad/popad 仅适用于 x86,在 x64 中无法使用。
向堆栈中压入 EAX,ECX,EDX,EBX,ESP,EBP,ESI,ESI 8个寄存器的值,或者从堆栈中弹出 0x20 字节到这 8 个通用寄存器。

lodsb、lodsw、lodsd、lodsq、stosb、stosw、stosd、stosq、movsb、movsw、movsd、movsq

ret n

2 中断和异常
2.1 中断和异常
| 中断/异常类型 | 描述 | 备注 |
|---|---|---|
| 硬件中断 | 外部中断,使用 32~255 号中断。 | |
| 硬件异常 | (1)0~31 号中,除了 #BP 与 #OF 异常以外的所有异常。 (2)能产生 ErrorCode 的硬件异常:双重错误 (#DF)、无效 TSS (#TS)、段不存在 (#NP)、栈段错误 (#SS)、通用保护异常 (#GP)、页错误 (#PF)、对齐检查 (#AC)。 |
产生 ErrorCode 的硬件异常,要向堆栈压入错误码 ErrorCode |
| 软件中断 | 软件中断指由 INT 指令执行的中断。 |
中断时需要进行段权限检查 CPL。 |
| 软件异常 | 软件异常指由 INT3 与 INTO 指令产生的 #BP 与 #OF 异常。 |
2.2 中断和异常列表
| 向量号 | 助记符 | 类型 | ErrorCode | 描述 | 来源 |
|---|---|---|---|---|---|
| 0 | #DE | 错误 | 无 | 除零错误 | DIV 和 IDIV指令 |
| 1 | #DB | 错误/陷阱 | 无 | 调试异常,用于软件调试 | 任何代码或数据引用 |
| 2 | / | 中断 | 无 | NMI中断 | 不可屏蔽的外部中断 |
| 3 | #BP | 陷阱 | 无 | 断点 | INT 3 指令 |
| 4 | #OF | 陷阱 | 无 | 溢出 | INTO 指令 |
| 5 | #BR | 错误 | 无 | 数组越界 | BOUND 指令 |
| 6 | #UD | 错误 | 无 | 无效指令(没有定义的指令) | UD2 指令(奔腾 Pro CPU 引入此指令)或任何保留的指令 |
| 7 | #NM | 错误 | 无 | 数学协处理器不存在或不可用 | 浮点或 WAIT/FWAIT 指令 |
| 8 | #DF | 中止 | 是(零) | 双重错误 (Double Fault) | 任何可能产生异常的指令、不可屏蔽中断或可屏蔽中断 |
| 9 | #MF | 错误 | 无 | 向协处理器传送操作数时检测到页错误(Page Faults)或段不存在,自从 486 把数学协处理器集成到 CPU 内部后,本异常便保留不用 | 浮点指令 |
| 10 | #TS | 错误 | 是 | 无效 TSS | 任务切换或访问 TSS |
| 11 | #NP | 错误 | 是 | 段不存在 | 加载段寄存器或访问系统段 |
| 12 | #SS | 错误 | 是 | 栈段错误 | 栈操作或加载 SS 寄存器 |
| 13 | #GP | 错误 | 是 | 通用保护(GP)异常,如果一个操作违反了保护模式下的规定,而且该情况不属于其他异常,则 CPU 便产生通用保护异常,很多时候也被翻译为一般保护异常 | 任何内存引用和保护性检查 |
| 14 | #PF | 错误 | 是 | 页错误 | 任何内存引用 |
| 15 | 保留 | / | / | / | / |
| 16 | #MF | 错误 | 无 | 浮点错误 | 浮点或 WAIT/FWAIT 指令 |
| 17 | #AC | 错误 | 是(零) | 对齐检查 | 对内存中数据的引用(486CPU 引入) |
| 18 | #MC | 中止 | 无 | 机器检查(Machine Check) | 错误代码和来源与型号有关(奔腾CPU 引入) |
| 19 | #XF | 错误 | 无 | SIMD 浮点异常 | SIMD 浮点指令(奔腾I CPU 引入) |
| 20~31 | 保留 | / | / | / | / |
| 32~255 | 用户定义中断 | 中断 | … | 可屏蔽中断 | 来自INTR的外部中断或 INT n指令 |



