教学提示
在正确理解每条指令的功能
基础上, 可以阅读和编写有
实际意义的程序段
西










位操作类指令
?位操作类指令以二进制位为基本单位
进行数据的操作;这是一类常用的指
令, 都应该特别掌握
?注意这些指令对标志位的影响
1,逻辑运算指令
AND, OR,XOR,NOT,TEST
2,移位指令
SHL,SHR,SAR
3,循环移位指令
ROL,ROR,RCL,RCR
西










逻辑与指令 AND
?对两个操作数执行逻辑与运算, 结果
送到目的操作数
?AND指令设置 CF = OF = 0,根据结果
设置 SF,ZF和 PF状态, 而对 AF未定义
AND reg,imm/reg/mem ; reg←reg ∧ imm/reg/mem
AND mem,imm/reg ; mem←mem ∧ imm/reg
只有相, 与, 的两位都是 1,结果才是 1;
否则, 结果为 0,即有, 0”为 0,全, 1”为 1。
AND
西










逻辑或指令 OR
?对两个操作数执行逻辑或运算, 结果
送到目的操作数
?OR指令设置 CF = OF = 0,根据结果设
置 SF,ZF和 PF状态, 而对 AF未定义
OR reg,imm/reg/mem ; reg←reg ∨ imm/reg/mem
OR mem,imm/reg ; mem←mem ∨ imm/reg
只要相, 或, 的两位有一位是 1,结果就
是 1否则, 结果为 0,即有, 1”为 1,全, 0”为
0。
OR
西










逻辑异或指令 XOR
?对两个操作数执行逻辑异或运算, 结
果送到目的操作数
?XOR指令设置 CF = OF = 0,根据结果
设置 SF,ZF和 PF状态, 而对 AF未定义
XOR reg,imm/reg/mem ; reg←reg ⊕ imm/reg/mem
XOR mem,imm/reg ; mem←mem ⊕ imm/reg
只有相, 异或, 的两位不相同, 结果才是
1;否则, 结果为 0,即相同为 0,相异为 1。
XOR
西










逻辑非指令 NOT
?对一个操作数执行逻辑非运算
?NOT指令是一个单操作数指令
?NOT指令不影响标志位
NOT reg/mem ; reg/mem← ~ reg/mem
按位取反, 原来是, 0”的位变
为, 1”;原来是, 1”的位变为, 0”
NOT
例:逻辑运算
mov al,45h ;逻辑与 al=01h
and al,31h ; CF=OF=0,SF=0,ZF=0,PF=0
mov al,45h ;逻辑或 al=75h
or al,31h ; CF=OF=0,SF=0,ZF=0,PF=0
mov al,45h ;逻辑异或 al=74h
xor al,31h ; CF=OF=0,SF=0,ZF=0,PF=1
mov al,45h ;逻辑非 al=0bah
not al ;标志不变
西










例:逻辑指令应用
AND指令可用于复位某些位 ( 同 0相与 ), 不
影响其他位:将 BL中 D3和 D0位清 0,其他位不变
and bl,11110110B
OR指令可用于置位某些位 ( 同 1相或 ), 不
影响其他位:将 BL中 D3和 D0位置 1,其他位不变
or bl,00001001B
XOR指令可用于求反某些位 ( 同 1相异或 ),
不影响其他位:将 BL中 D3和 D0位求反, 其他不变
xor bl,00001001B
西










西










测试指令 TEST
?对两个操作数执行逻辑与运算, 结果
不回送到目的操作数
?AND指令设置 CF = OF = 0,根据结果
设置 SF,ZF和 PF状态, 而对 AF未定义
TEST reg,imm/reg/mem ; reg∧ imm/reg/mem
TEST mem,imm/reg ; mem∧ imm/reg
只有相, 与, 的两位都是 1,结
果才是 1;否则,, 与, 的结果为
0
TEST
例:测试为 0或 1
test al,01h ;测试 AL的最低位 D0
jnz there ;标志 ZF=0,即 D0=1;则程序转移到 there
..,;否则 ZF=1,即 D0=0,顺序执行
there,...
TEST指令通常用于检测一些条件是否
满足, 但又不希望改变原操作数的情况
TEST
西










西










移位指令 ( shift)
?将操作数移动一位或多位, 分成逻辑移位和
算术移位, 分别具有左移或右移操作
SHL reg/mem,1/CL;逻辑左移,最高位进入 CF,最低位补 0SHR reg/mem,1/CL;逻辑右移,最低位进入 CF,最高位补 0SAL reg/mem,1/CL;算术左移,最高位进入 CF,最低位补 0SAR reg/mem,1/CL;算术右移,最低位进入 CF,最高位不变
SAL与 SHL相同
演示
图示
西










移位指令的操作数
?移位指令的第一个操作数是指定
的被移位的操作数, 可以是寄存
器或存储单元
?后一个操作数表示移位位数, 该
操作数 为 1,表示移动一位;当移
位位数 大于 1时, 则用 CL寄存器值
表示, 该操作数表达为 CL
西










移位指令对标志的影响
?按照移入的位设置进位标志 CF
?根据移位后的结果影响 SF,ZF,PF
?对 AF没有定义
?如果进行一位移动, 则按照操作数的
最高符号位是否改变, 相应设置溢出
标志 OF:如果移位前的操作数最高位
与移位后操作数的最高位不同 ( 有变
化 ), 则 OF = 1;否则 OF = 0。 当移
位次数大于 1时, OF不确定
例:移位指令
mov cl,4
mov al,0f0h ; al=f0h
shl al,1 ; al=e0h; CF=1,SF=1,ZF=0,PF=0,OF=0
shr al,1 ; al=70h; CF=0,SF=0,ZF=0,PF=0,OF=1
sar al,1 ; al=38h; CF=0,SF=0,ZF=0,PF=0,OF=0
sar al,cl ; al=03h; CF=1,SF=0,ZF=0,PF=1
西










西










循环移位指令 ( rotate)
?将操作数从一端移出的位返回到另一
端形成循环, 分成不带进位和带进位,
分别具有左移或右移操作
ROL reg/mem,1/CL ;不带进位循环左移
ROR reg/mem,1/CL ;不带进位循环右移
RCL reg/mem,1/CL ;带进位循环左移
RCR reg/mem,1/CL ;带进位循环右移
图示
图示
西










循环移位指令对标志的影响
?按照指令功能设置进位标志 CF
?不影响 SF,ZF,PF,AF
?如果进行一位移动, 则按照操作数的
最高符号位是否改变, 相应设置溢出
标志 OF:如果移位前的操作数最高位
与移位后操作数的最高位不同 ( 有变
化 ), 则 OF = 1;否则 OF = 0。 当移
位次数大于 1时, OF不确定
例,32位数移位;将 DX.AX中 32位数值左移一位
shl ax,1
rcl dx,1
DX AXCF
0
西










例:位传送;把 AL最低位送 BL最低位, 保持 AL不变
ror bl,1
ror al,1
rcl bl,1
rol al,1
AL,BL CF
BL CF
ALCF
AL之 D0西










例,BCD码合并; AH.AL分别存放着非压缩 BCD码的两位;将它们合并成为一个压缩 BCD码存 AL
and ax,0f0fh ;保证高 4位为 0
mov cl,4
rol ah,cl ;也可以用 shl ah,cl
add al,ah ;也可以用 or al,ah
西










西










串操作类指令
? 串操作指令是 8086指令系统中比较独
特的一类指令, 采用比较特殊的数据串
寻址方式, 在操作主存连续区域的数据
时, 特别好用, 因而常用
重点掌握,MOVS STOS LODS
CMPS SCAS REP
一般了解,REPZ/REPE REPNZ/REPNE
西










串数据类型
?串操作指令的操作数是 主存中连
续存放的数据串 ( String) —— 即
在连续的主存区域中, 字节或字的
序列
?串操作指令的 操作对象是以字
( W) 为单位的字串, 或是以字节
( B) 为单位的字节串
西










串寻址方式
?源操作数用寄存器 SI寻址, 默认在数据段
DS中, 但允许段超越,DS:[SI]
?目的操作数用寄存器 DI寻址, 默认在附加段
ES中, 不允许段超越,ES:[DI]
?每执行一次串操作指令, SI和 DI将自动修改:
? ± 1( 对于字节串 ) 或 ± 2( 对于字串 )
? 执行指令 CLD指令后, DF = 0,地址指针
增 1或 2
? 执行指令 STD指令后, DF = 1,地址指针
减 1或 2
西










串传送 MOVS( move string)
?把字节或字操作数从主存的源地
址传送至目的地址
MOVSB;字节串传送,ES:[DI]←DS:[SI]; SI←SI ± 1,DI←DI ± 1
演示
MOVSW;字串传送,ES:[DI]←DS:[SI]; SI←SI ± 2,DI←DI ± 2
演示
例:字节串传送
mov si,offset source
mov di,offset destination
mov cx,100 ; cx← 传送次数
cld ;置 DF=0,地址增加
again,movsb ; 传送一个字节
dec cx ;传送次数减 1
jnz again;判断传送次数 cx是否为 0;不为 0,则到 again位置执行指令;否则, 结束
offset是汇编操作符,
求出变量的偏移地址
演示
西










例:字串传送
mov si,offset source
mov di,offset destination
mov cx,50 ; cx← 传送次数
cld ;置 DF=0,地址增加
again,movsb ; 传送一个字
dec cx ;传送次数减 1
jnz again;判断传送次数 cx是否为 0;不为 0,则到 again位置执行指令;否则, 结束
西










西










串存储 STOS( store string)
?把 AL或 AX数据传送至目的地址
STOSB;字节串存储,ES:[DI]←AL; DI←DI ± 1
STOSW;字串存储,ES:[DI]←AX; DI←DI ± 2
例:串存储
mov ax,0
mov di,0
mov cx,8000h; cx← 传送次数 ( 32× 1024)
cld ; DF=0,地址增加
again,stosw ;传送一个字
dec cx ;传送次数减 1
jnz again ;传送次数 cx是否为 0
可将 CLD改为 STD吗? 如何改用 STOSB?
可不用给 DI赋值吗?
DI为偶数即可
西










西










串读取 LODS( load string)
?把指定主存单元的数据传送给 AL或 AX
LODSB;字节串读取,AL←DS:[SI]; SI←SI ± 1
LODSW;字串读取,AX←DS:[SI]; SI←SI ± 2
例:串读取- 1
mov si,offset block
mov di,offset dplus
mov bx,offset dminus
mov ax,ds
mov es,ax;数据都在一个段中, 所以设置 es=ds
mov cx,count ; cx← 字节数
cld
西










例:串读取- 2
go_on,lodsb ;从 block取出一个数据
test al,80h;检测符号位, 判断是正是负
jnz minus;符号位为 1,是负数, 转向 minus
stosb;符号位为 0,是正数, 存入 dplus
jmp again;程序转移到 again处继续执行
jnz go_on ;完成正负数据分离
西










例:串读取- 3
minus:xchg bx,di
stosb ;把负数存入 dminus
xchg bx,di
again:dec cx ;字节数减 1
jnz go_on ;完成正负数据分离
西










西










串比较 CMPS( compare string)
?将主存中的源操作数减去至目的操作
数, 以便设置标志, 进而比较两操作
数之间的关系
CMPSB;字节串比较,DS:[SI]- ES:[DI]; SI←SI ± 1,DI←DI ± 1
CMPSW;字串比较,DS:[SI]- ES:[DI]; SI←SI ± 2,DI←DI ± 2
例:比较字符串
mov si,offset string1
mov di,offset string2
mov cx,count
cld
again,cmpsb ;比较两个字符
jnz unmat ;有不同字符, 转移
dec cx
jnz again ;进行下一个字符比较
mov al,0 ;字符串相等, 设置 00h
jmp output ;转向 output
unmat,mov al,0ffh ;设置 ffh
output:mov result,al;输出结果标记
西










西










串扫描 SCAS( scanstring)
?将 AL/AX减去至目的操作数, 以便设
置标志, 进而比较 AL/AX与操作数之
间的关系
SCASB;字节串扫描,AL- ES:[DI]; DI←DI ± 1
SCASW;字串扫描,AX- ES:[DI]; DI←DI ± 2
例:查找字符串
mov di,offset string
mov al,20h
mov cx,count
cld
again,scasb ;搜索
jz found ;为 0( ZF=1), 发现空格
dec cx ;不是空格
jnz again ;搜索下一个字符
..,;不含空格, 则继续执行
found,...
西










西










重复前缀指令 ( repeat)
?串操作指令执行一次, 仅对数据串中
的一个字节或字量进行操作 。 但是串
操作指令前, 都可以加一个重复前缀,
实现串操作的重复执行 。 重复次数隐
含在 CX寄存器中
?重复前缀分 2类, 3条指令:
? 配合不影响标志的 MOVS,STOS( 和
LODS) 指令的 REP前缀
? 配合影响标志的 CMPS和 SCAS指令的
REPZ和 REPNZ前缀
西










REP重复前缀指令
?REP前缀可以理解为:当数据串
没有结束 ( CX≠0), 则继续传送
?例 2.36和 例 2.37中, 程序段的最后
3条指令, 可以分别替换为:
REP MOVSB 和 REP STOSW
REP ;每执行一次串指令,CX减 1;直到 CX= 0,重复执行结束
西










REPZ重复前缀指令
?REPZ/REPE前缀可以理解为:当
数据串没有结束 ( CX≠0), 并且
串相等 ( ZF= 1), 则继续比较
REPZ ;每执行一次串指令,CX减 1;并判断 ZF是否为 0,;只要 CX= 0或 ZF= 0,重复执行结束
西










REPNZ重复前缀指令
?REPNZ/REPNE前缀可以理解为:
当数据串没有结束 ( CX≠0), 并
且串不相等 ( ZF= 0), 则继续比

REPZ ;每执行一次串指令,CX减 1;并判断 ZF是否为 1,;只要 CX= 0或 ZF= 1,重复执行结束
例:比较字符串
mov si,offset string1
mov di,offset string2
mov cx,count
cld
repz cmpsb ;重复比较两个字符
jnz unmat ;字符串不等, 转移
mov al,0 ;字符串相等, 设置 00h
jmp output ;转向 output
unmat,mov al,0ffh ;设置 ffh
output:mov result,al;输出结果标记
解释
西










例:查找字符串
mov di,offset string
mov al,20h
mov cx,count
cld
repnz scasb ;搜索
jz found ;为 0( ZF=1), 发现空格
..,;不含空格, 则继续执行
found,...
西










第 2章 教学要求 ( 4)
1,熟悉 串操作寻址特点
2,掌握基本指令,AND/ OR/ XOR/ NOT/
TEST,SHL/ SHR/ SAR,ROL/ ROR/
RCL/ RCR,MOVS/ LODS/ STOS,REP
3,熟悉特色指令,CMPS/ SCAS
4,了解不常使用的指令,REPZ/ REPNZ
5,习题 3( p72) 2.23 2.25 2.26
西










课间休息