0%

汇编课程记录 5

算术运算指令

双操作数指令必须有一个操作数在寄存器中(除源操作数是立即数的情况)
单操作数指令不允许使用立即数

条件标志位
CF 有进位为 1 无进位为 0
ZF 结果为零
SF 符号
OF 溢出,若两个操作数符号相同而结果的符号与之相反时为 1

加法指令

1
2
3
4
5
6
7
8
9
ADD DST,SRC

ADC DST,SRC
;(DST) ← (SRC)+(DST)+CF
;带进位加法指令

INC OPR
;(OPR) ← (OPR)+1
;加 1 指令

除 INC 指令不影响 CF 外,其余都影响标志位

减法指令

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
SUB DST,SRC

SBB DST,SRC
;(DST) ← (DST)-(SRC)-CF
;带借位减法指令

DEC OPR
;减 1 指令

NEG OPR
;类似 (OPR) ← 0FFFFH-(OPR)+1
;求补指令

CMP OPR1,OPR2
;比较指令,执行 SUB 操作但不保存结果,只根据结果设置条件标志位
;两操作数不能同时为存储器操作数

乘法指令
目操作数必须是累加器,字节运算为 AL,字运算为 AX
源操作数允许立即数外的寻址方式
两个 8 位数相乘得 16 位乘积存放在 AX;两个 16 位数相乘得 32 位乘积,高字位送 DX 低字位送 AX

1
2
3
4
5
6
7
MUL SRC
;无符号数乘法指令
;(AX) ← (AL)*(SRC)
;(DX,AX) ← (AX)*(SRC)

IMUL SRC
;有符号数乘法指令

MUL 指令中,若高一半为 0,即字节操作的 (AH) 或字操作的 (DX) 为 0,则 CF OF 为 0,否则为 1,可以用于检查字节相乘的结果是字节还是字,或检查字相乘的结果是字还是双字
IMUL 指令中,若乘积的高一半是低一半的符号扩展,则 CF OF 均为 0,否则均为 1

除法指令

1
2
3
4
5
6
7
8
9
10
11
DIV SRC
;(AL) ← (AX)/(SRC) 的商
;(AH) ← (AX)/(SRC) 的余数
;源操作数为 8 位时,被除数必须 16 位
;被除数必须预先存在 AX 中
;(AX) ← (DX,AX)/(SRC) 的商
;(DX) ← (DX,AX)/(SRC) 的余数
;被除数必须预先存在 DX,AX 中

IDIV SRC
;有符号数除法指令

逻辑操作指令

逻辑运算指令

1
2
3
4
AND DST,SRC
;(DST) ← (DST)∧(SRC)
;逻辑与指令
;源为立即数,需要清零的位为 0,不变的位设为 1
1
2
3
4
OR DST,SRC
;(DST) ← (DST)V(SRC)
;逻辑或指令
;需要置一的位为 1,不变的位设为 0
1
2
3
4
5
6
7
8
9
10
11
12
NOT OPR
;逻辑非指令,按位取反

XOR DST,SRC
;异或指令
;需要取反的位设为 1,不变的位设为 0
XOR AX,AX
;给寄存器清零,同时使 CF 清零

TEST OPR1,OPR2
;用 AND 的结果设置条件标志位 ZF
;可测试目的某些位是否为 0

移位指令

1
2
3
SHL OPR,CNT
SAL OPR,CN
;逻辑左移指令和算术左移指令

将操作数 OPR 向左移动 CNT 指定的次数,低位补入相应个数的 0,CF 的内容为 OPR 最后移出的数位值
若需要移位的次数大于 1 则需要把位移次数置于 CL 寄存器

1
2
3
4
5
6
SHR OPR,CNT
;逻辑右移指令,参考逻辑左移

SAR OPR,CNT
;算术右移指令
;最高位保持不变

上面四条移位指令都可作字或字节操作,当 CNT=1 时,且移位后最高有效位发生改变,则 OF 置 1,否则置 0
算术位移指令适用于有符号数,逻辑移位指令用于无符号数

1
2
3
4
5
6
ROL OPR,CNT
ROR OPR,CNT
;循环左移指令和循环右移指令
;将操作数 OPR 的最高最低位连接
;将环中所有位一起向左/右循环移动 CNT 次
;CF 的内容为 OPR 中最后移出的数值位
1
2
3
4
5
RCL OPR,CNT
RCR OPR,CNT
;带进位循环左移指令和循环右移指令
;将操作数 OPR 与 CF 标志位一起连接成环
;CF 为 OPR 最后移到 CF 中的数值

这四条指令也只影响 OF(当 CNT=1 时) 和 CF 位,循环移位指令可以改变操作数中所有位的位置

串处理指令

将一组存放在存储器连续单元的数据称为数据串。而数据传送指令每次只能传送一个数据,故 CPU 为数据串提供了一组完成数据串传送的指令

若加重复前缀则要求将数据串长度/重复次数送 CX
源串地址应设置在 (DS:SI) 中,可指定段跨越前缀;目的串地址应设置在 (ES:DI) 中,不能指定段跨越前缀
操作数不是串时只能使用累加器 (AL/AX)
所有串处理指令前都必先对方向标志 (DF) 置值

  • CLD 使 DF=0,控制地址自动增加 1(字)/2(字节)
  • STD 使 DF=1,控制地址自动减少 1(字)/2(字节)

重复前缀
配合串处理指令的重复操作

1
2
3
4
5
6
REP 串指令
;重复串操作
;1. 如 (CX)=0,则退出串操作,否则继续执行
;2. (CX) ← (CX)-1
;3. 执行其后的串操作
;4. 从 1 重复
1
2
3
4
5
6
7
8
REPE/REPZ 串指令
;相等则重复串操作
;即 (CX)=0 或 ZF=0
;增加了两个操作数不等则退出串操作

REPNE/REPNZ 串指令
;不相等则重复串操作
;即 (CX)=0 或 ZF=1

与 REP 配合的指令

1
2
3
4
5
6
7
MOVS DST,SRC
MOVSB
MOVSW
;串传送指令
;((ES:DI)) ← ((DS:SI))
;(SI) ← (SI) ±1/±2
;(DI) ← (DI) ±1/±2

不影响标志位
执行前的准备工作:

  • 将存放于数据段的源串首地址(DF=0)或末地址(DF=1)放入 SI
  • 将存放于附加段的目的串首地址(DF=0)或末地址(DF=1)放入 SI
  • 将数据串长度放入 CX 寄存器
  • 建立方向标志
1
2
3
4
5
6
STOS DST
STOSB
STOSW
;将数存入串指令
;((ES:DI)) ← (AL) 或 (AX)
;(DI) ← (DI) ±1/±2

与 REP 配合时可把 AL/AX 的内容存入长度为 (CX) 的缓冲区,常用于对一段数据区进行初始化,不影响标志位

与 REPE/REPZ REPNE/REPNZ 配合的指令

1
2
3
4
5
6
7
CMPS SRC,DST
CMPSB
CMPSW
;串比较指令
;以 ((ES:DI)) - ((DS:SI)) 的结果设置标志位
;(SI) ← (SI) ±1/±2
;(DI) ← (DI) ±1/±2

可配合找出两组数据串中不同/相同的字符

1
2
3
4
5
6
SCAS DST
SCASB
SCASW
;串查找指令
;以 (AL) 或 (AX) - ((ES:DI)) 的结果设置标志位
;(DI) ← (DI) ±1/±2

可配合找出两组数据串中与指定字符不同/相同的元素

不与重复前缀配合的指令

1
2
3
4
5
6
LODS SRC
LODSB
LODSW
;从串中取数指令
;(AL) 或 (AX) ← ((DS:SI))
;(SI) ← (SI) ±1/±2