问题描述
在学习《汇编语言(第三版)王爽 著》过程中,我们整理出该部分笔记:1)便于日后查阅;2)将我们记忆错误的地方,整理下来,形成对照;
该部分笔记将记录:在 x86 中,常用指令、使用说明,以及相关知识点。
注意事项
该部分的笔记:旨在记录我们理解错误的内容,不能作为汇编语言的学习教程。
解决方案
Classification of Instruction Sets
我们使用 ORACLE/x86 Assembly Language Reference Manual/3.2 General-Purpose Instructions 分类方法,按照该分类进行学习笔记的整理。
关于指令分类:
1)在处理器厂商的手册中,并没有对指令集分类,因此我们也不打算按分类整理指令;
2)但是,在分类列表中,我们可能会添加“类别”列,以辅助我们记忆;
3)指令的分类,参考 ORACLE/x86 Assembly Language Reference Manual 文档;
00.Data Transfer Instructions
01.Binary Arithmetic Instructions
02.Decimal Arithmetic Instructions
03.Logical Instructions
04.Shift and Rotate Instructions
05.Bit and Byte Instructions
06.Control Transfer Instructions
07.String Instructions => 串操作指令
08.I/O Instructions
09.Flag Control (EFLAG) Instructions => 标志处理指令
10.Segment Register Instructions
11.Miscellaneous Instructions
MUL – 乘法
指令格式:
MUL <register>
MUL <memory location>
对于乘数:
两个乘数:要么全为 8-bit ;要么全为 16-bit ;
当两个乘数全为 8-bit 时:一个乘数放在 AL 中;一个乘数放在 8-bit 寄存器 或 内存字节单元 中;
当两个乘数全为 16-bit 时:一个乘数放在 AX 中;一个乘数放在 16-bit 寄存器 或 内存字单元 中;
对于结果:
当两个乘数全为 8-bit 时:结果保存在 AX 中;
当两个乘数全为 16-bit 时:结果的高位保存在 DX 中;结果的低位保存在 AX 中;
使用示例:
; 示例一、计算 100x10 ; 此时乘数全为 8 位 mov al, 100 mov bl, 10 mul bl ; 计算结果保存在 AX 中 ; 示例二、计算 100x10000 ; 此时乘数 10000 需要使用 16 位寄存器 mov ax, 100 mov bx, 10000 mul bx ; 计算结果:低位保存在 AX 中;高位保存在 DX 中 ; 示例三、使用内存单元 ; 将内存地址 ds:[0] 的字单元乘以 10000 mov ax, 10000 mul word ptr ds:[0] ; 结果保存在 AX 中
DIV – 除法
对于除数、被除数:
除数有 8-bit 和 16-bit 两种,保存在 寄存器 或者 内存单元 中。
当除数为 8-bit 时,被除数为 16-bit ,默认存放在 AX 寄存器中
当除数为 16-bit 时,被除数为 32-bit ,在 DX 中存放高 16-bit ,在 AX 中存放低 16-bit 。
对于结果:
当除数为 8-bit 时,计算结果为 8-bit ,在 AL 中存放商,在 AH 中存放余数
当除数为 16-bit 时,计算结果为 8-bit ,在 AX 中存放商,在 DX 中存放余数
使用示例:
; 示例一、100001/100 mov dx, 1 mov ax, 86a1H mov bx, 100 div bx ; 商 => ax,余数 => dx ; 示例二、1001/100 mov ax, 1001 mov bl, 100 div bl ; 商 => al,余数 => ah
INT – 引发中断
指令格式:
int n,其中 n 为中断类型码
执行过程:
1)获取中断类型码(n) => 用于在查找中断向量表中定位中断程序入口。
2)将标志寄存器入栈
3)IF = 0,TF = 0;
4)先将 CS 入栈,再将 IP 入栈;
5)(IP) = (4 * n), (CS) = (4 * n + 2)
其他内容:
Can an x86 assembly interrupt service routine call another interrupt?
MOVSB, MOVSW – 串传送
将字节(MOVSB)或字(MOVSW)从 ds:[si] 移动到 es:[di] 中,并增加(DF=0)或较少(DF=1) si 与 di 寄存器
指令格式:
MOVSB
执行过程:
((ES) * 16 + (DI)) = ((DS) * 16 + (SI)) if DF == 0 (si) = (si) + 1, (di) = (di) + 1 if DF == 1 (si) = (si) - 1, (di) = (di) - 1
指令 MOVSW 类似,但是移动字,同时以 2 为步长修改 si di 寄存器。
REP – 重复
根据 cx 的值,重复执行串传送指令
指令格式:
REP MOVSB
REP MOVSW
执行过程(相当于):
l: MOVSB loop l
SHL / SHR – 逻辑位移
SHR,对目的操作数进行位移。指令格式:
Instruction | Description |
---|---|
SHR r8/m8, 1 | |
SHR r16/m16, 1 | |
SHR r8/m8, imm8 | |
SHR r16/m16, imm8 | |
SHR r8/m8, CL | |
SHR r16/m16, CL |
相关链接
Wikipedia/x86 instruction listings
ORACLE/x86 Assembly Language Reference Manual
参考文献
《汇编语言(第三版)王爽 著》
Wikipedia/FLAGS register
百度文库/汇编指令分类介绍
Wikipedia/x86 instruction listings
ORACLE/x86 Assembly Language Reference Manual