1.19k likes | 1.33k Views
三. 逻辑指令. 指令分类. 例 : 1 1 0 1 1 1 0 0 ∧ 1 0 1 1 1 0 1 0 1 0 0 1 1 0 0 0. 例 : 1 0 1 0 1 1 0 0 ∨ 0 0 1 1 1 0 0 1 1 0 1 1 1 1 0 1. 逻辑运算 : 与、或、非、异或. 特点:二进制数运算 , 按位进行. ' 与 ' 运算: 有 0 则 0 ,全 1 则. ' 或 ' 运算: 有 1 则 1 ,全 0 则 0. 例 : 1 0 1 1 1 0 1 0
E N D
三.逻辑指令 指令分类
例:1101 1100 ∧ 1011 1010 1001 1000 例:1010 1100 ∨ 0011 1001 1011 1101 逻辑运算 :与、或、非、异或 • 特点:二进制数运算 ,按位进行 '与'运算:有0则0,全1则 '或'运算:有1则1,全0则0
例: 1011 1010 0100 0101 例:1010 1100 ∨ 0011 1001 1001 0101 '非'运算: 0则1,1则0 '异或'运算:异则1,同则0
置CF、OF为0,AF不定 ( 无意义) SF、ZF、PF据结果置位 其他指令 • AND AL , 0000 1111B • OR BX , 00FFH • NOT CL • XOR DL, AL • TEST AL, 0000 0001B • 除NOT指令单操作数外,其它均为双操作数 • 可进行字节或字操作 • NOT指令不影响标志 • TEST只影响标志位,不影响操作数
例 数字字符的ASCII → 对应的二进制数 • 0011 1001B 39 H • ∧ 0000 1111 B 0F H • 0000 1001B 09 H • 应用: • MOV AH, 1 ;利用DOS调用 • INT 21H ;从键盘输入字符到AL中 • AND AL, 0000 1111B ;高4位为0,低4位不变 • 、、、
逻辑运算常用于使操作数的某位为0或1, 或测试某位为0还是1。 • 使某位为1 • 用该位与1 相或,不变的位与0或。 • 使某位为0 • 用该位与0 相与,不变的位与1与。 • 使某位求反 • 用该位与1 异或,不变的位与0异或。 • 测试某位的值 • 用TEST指令,据标志判断
1 0 1 0 0 0 1 0 为0, 允许键盘中断 为1, 禁止 D7 D6 D5 D4 D3 D2 D1 D0 7 6 5 4 3 2 1 0 例21H端口管理中断系统,管理8个外设的中断 允许键盘中断: IN AL,21H ;读入21端口内容 AND AL,1111 1101B ;置D1 = 0,其他位不变 OUT 21H ,AL ;送出屏蔽字到21H端口 禁止键盘中断: IN AL,21H OR AL,0000 0010B ;使D1为1 OUT 21H,AL
1 0 1 0 0 0 1 0 D7 D6 D5 D4 D3 D2 D1 D0 7 6 5 4 3 2 1 0 例379H端口的D7存放打印机的状态 为0, 表示打印机忙 为1, 打印机空闲 • 用查询方式控制打印机工作: • MOV DX, 379H • ask: IN AL, DX ;从379H端口读状态 • TEST AL, 1000 0000B ;检测D7位 • JZ ask ;为0,继续查询 • print:、、、 ;输出字符打印
指令格式 执行操作 1 CL SHL oprd, CF 0 1 CL SAL oprd, CF 0 1 CL SHR oprd, 0 CF 1 CL CF SAR oprd, 2. 移位指令
SHL CF 0 SAL CF 0 SHR 0 CF SAR CF • 移位规则 • ▲ 左移: 高位 ← 低位 • 右移: 高位 → 低位 • ▲ 移出位进入CF标志 • ▲ 对移位指令,移出CF标志后丢失 • ▲ 逻辑左移、算术左移的结果相同 • ▲ 逻辑右移,新移入的信息以0填入 • 算术右移,保持最高有效位原来的值(符号为不变)
算术左移和逻辑左移为什么会一样呢?既然如此,为什么还有两种指令呢?算术左移和逻辑左移为什么会一样呢?既然如此,为什么还有两种指令呢? • 算术左移和算术右移主要用来进行有符号数的倍增、减半; 逻辑左移和逻辑右移主要用来进行无符号数的倍增、减半。 • 算术左移和算术左移虽然方式是一样的,但他们表示的移位后数的范围是不一样的,有符号数左移(算术左移)位后的范围是-128——127【指8位】.而无符号数(算术左移)左移的范围是0——255.【指8位】
例 若(AL)=96H, CF=0 执行 SHL AL, 1 例 若(AL)=96H, CF=0, (CL) =2 执行 SAR AL, CL 执行后:(AL)=E5H ,CF=1 执行前:(AL)=96H ,CF=0 执行后:(AL)=2CH ,CF=1 0 1 1 1 0 1 0 0 0 1 1 0 0 1 0 1 0 1 0 0 1 1 1 1 0 1 1 0 0 1 0 0 执行前:(AL)=96H ,CF=0 CF
指令格式 执行操作 1 CL CF ROL oprd, 1 CL CF ROR oprd, 1 CL CF RCL oprd, 1 CL CF RCR oprd, 3. 循环移位指令
ROL CF ROR CF RCL CF RCR CF • 移位规则 • ▲ 左移: 高位 ← 低位 • 右移: 高位 → 低位 • ▲ 移出位进入CF标志 • ▲ 对循环移位指令,改变各位的位置,信息不丢失 • ▲ 带进位循环移位,CF标志参加循环移位
例 若(AL)= 96H, CF=0 执行 ROL AL, 1 例 若(AL)= 96H, CF=0, (CL)=2 执行 RCR AL, CL (AL)=96H CF=0 (AL)=96H, CF=0 (AL)=25H CF=1 0 1 0 0 1 0 1 1 执行前: 执行后: (AL)=2DH, CF=1 1 0 0 1 0 1 1 0 1 0 1 0 0 1 0 1 执行前: 执行后: 1 0 0 1 0 0 0 1
注意事项: • SHL AL, 1 • SHR AL, CL • ROL BX, 1 • RCR AL, CL • 源操作数为移位的次数 • 为1可在指令中直接给出 • 大于1时,移位次数需由CL给出 • RCR AX,5 SHL BL, AL • 目的操作数类型决定操作类型 • SAL BL,CL 字节操作 • ROL BX,CL字操作 • oprd可以是reg/mem • 可进行字节或字操作 当移位次数
SHL AL, 1 • ROL BX, 1 • 对标志位的影响 • ▲移位指令: • ①据结果设置CF、SF、ZF、PF,对AF无定义 • ②OF只在移位次数为1时有效,其他无定义 • 移位后,最高有效位发生变化,则OF=1,否则为0 • ▲对循环移位指令: • ①据移位结果设置CF,对其他标志无影响 • ②OF标志与移位指令同 CF 0 CF
逻辑移位可用于无符号数乘除 • 算术移位 、、 带符号数 、、 • 左移一次,相当于乘2 • 右移一次,相当于除2 • 例 将AL中的带符号数乘10 , 若(AL)=X • SAL AL ,1 ; (AL)=2X • MOV BL ,AL ; (BL)=2X • SAL AL ,1 ; (AL)=4X • SAL AL ,1 ; (AL)=8X • ADD AL ,BL ; (AL)=(8X+2X)=10X
循环移位指令可用来检测寄存器或存储单元中含1或含0的个数,因为用小循环指令循环8次,数据又恢复了,但对CF进行检测,就可计出1或0的个数;大循环指令要循环9次,数据也恢复了。循环移位指令可用来检测寄存器或存储单元中含1或含0的个数,因为用小循环指令循环8次,数据又恢复了,但对CF进行检测,就可计出1或0的个数;大循环指令要循环9次,数据也恢复了。 例:将AL的高4位与低4位互换。 MOV CL,4 ROL AL,CL
其机器码占一个字节单元, 在调试程序时,修改程序用。 例: (也可用NOP指令进行短延时(教材中的一些例子用到) • ② 空操作指令NOP • 格式NOP • 指令不执行任何操作
四.串处理指令 • 串的基本概念 顺序存放在内存中的一组数据,称为串。 • 用串的首(末)地址、元素类型、串的长度表示。
串操作种类 • ①串传送 • 将串从内存某一区域传送到另一区域。 • ② 从串取 • 从串中取出某一元素。 • ③ 存入串 • 将某个数据存入串中。 • ④ 串比较 • 对两个串进行比较。 • ⑤ 搜索串 • 在串中搜索(查找)某数据(关键字)
串处理指令格式 • 重复控制前缀 串指令 • 控制重复次数 基本操作 • MOVSB、MOVSW串传送 • REP LODSB、LODSW从串取 • REPZ STOSB、STOSW存入串 • REPNZ CMPSB、CMPSW串比较 • SCASB、SCASW搜索串 • 例REP MOVSB • REPZ CMPSB • REPNZ SCASW
① 串指令 • 串传送 MOVS • 从串取 LODS • 存入串 STOS • 串比较 CMPS • 搜索串 SCAS
串指令的特点 • ① 指令给出串操作的种类、类型,而操作数隐含给出。 • 如 MOVSB ;字节 • MOVSW ;字 • ② 源串 由DS : SI指向的单元 • 目的串 由ES : DI指向的单元 • ③ 指令执行后,指针据DF标志、操作类型自动修改 • 字节操作 1 ; 字操作 2 • DF= 0 用 + ; DF= 1 用 -
④对只有一个存储器操作数的串指令 • 如 LODS(从串取) • STOS(存入串) • SCAS(搜索串) • 另一个操作数在 AL (字节操作) 或 AX (字操作) • ⑤CMPS(串比较)、SCAS(串搜索)影响标志, • MOVS(串传送)、LODS(从串取)、STOS(存入串)不影响标志。
串传送 • ◢ ◢ 格式 MOVSB字节传送 • MOVSW字传送 • ◢ ◢MOVSB 执行操作 • (ES:DI ) ← (DS:SI ) 字节传送 • (SI ) ← (SI ) 1 修改源串指针 • (DI) ← (DI ) 1 修改目的串指针 • 其中: DF = 0 ,用 + • DF = 1 ,用 - • ◢ ◢MOVSW 执行操作 • (ES:DI ) ← (DS:SI ) 字传送 • (SI ) ← (SI ) 2 修改源串指针 • (DI ) ← (DI ) 2 修改目的串指针
从串取 • ◢ ◢ 格式 LODSB 取字节 • LODSW 取字 • ◢ ◢ LODSB执行操作 • (AL) ← (DS:SI ) 从源串取入AL • (SI ) ← (SI ) 1 修改源串指针 • ◢ ◢LODSW执行操作 • (AX ) ← (DS:SI ) 从源串取入AX • (SI ) ← (SI ) 2 修改源串指针
存入串 • ◢ ◢ 格式 STOSB 存入字节 • STOSW 存入字 • ◢ ◢STOSB执行操作 • (ES:DI) ← (AL)将AL存入目的串 • (DI ) ← (DI ) 1 修改目的串指针 • ◢ ◢ STOSW执行操作 • (ES:DI) ← (AX)将AX存入目的串 • (DI) ← (DI ) 2 修改目的串指针
串比较 • ◢ ◢格式 CMPSB字节比较 • CMPSW字比较 • ◢ ◢CMPSB 执行操作 • (DS:SI ) - (ES:DI ) 字节比较 • (SI ) ← (SI ) 1 修改源串指针 • (DI ) ← (DI ) 1 修改目的串指针 • ◢ ◢CMPSW 执行操作 • (DS:SI ) - (ES:DI ) 字比较 • (SI ) ← (SI ) 2 修改源串指针 • (DI ) ← (DI ) 2 修改目的串指针 • 注意:1. 源串 - 目的串 • 2. 两数相减,只影响标志,不影响操作数
搜索串 • ◢ ◢格式 SCASB取字节 • SCASW取字 • ◢ ◢SCASB执行操作 • (AL) - (ES:DI ) 从目的串搜索字节 • (DI ) ← (DI ) 1 修改目的串指针 • ◢ ◢SCASW执行操作 • (AX ) - (ES:DI ) 从目的串搜索字节 • (DI) ← (DI ) 2 修改目的串指针 • 两数相减,只影响标志,不影响操作数。
② 重复控制前缀 • 重复前缀REP • 当相等重复前缀REPZ /REPE • 当不相等重复前缀REPNZ /REPNE
重复前缀REP • 执行过程: • (1)当(CX)= 0,结束REP, • 执行REP下一条指令。 • (2)当(CX)≠0,将CX 的 内容减1, • 执行REP后的串指令,返回 (1)。 • 例LEA DI, destination • LEA SI, source • MOV CX,20 • REP MOVSB • MOV AX, 0 • 只在(CX)=0时退出循环
当相等重复前缀REPZ • 执行过程: • (1)当(CX)= 0 , 结束REPZ, • 执行REPZ下一条指令; • (2)当(CX)≠0,将CX 的内容减1, • 执行REPZ后的串指令; • (3)当ZF = 1, 返回 (1) ; • (4)当ZF≠1, 则结束REPZ, • 执行REPZ下一条指令。 • (CX)减1操作不影响标志 • ZF标志由串操作决定
当不相等重复前缀REPNZ • 执行过程: • (1)当(CX )= 0 , 结束REPNZ, • 执行REPNZ下一条指令。 • (2)当(CX)≠0,将CX 的内容减1, • 执行REPNZ后的串指令。 • (3)当ZF = 0, 返回(1); • (4)当ZF≠0, 则结束REPNZ, • 执行REPNZ下一条指令。
例1用REP MOVS进行数据块传送。 • 编程: • ①设置传送方向 • 用CLD 使DF = 0, 地址增加方向(正向) • 用STD 使 DF = 1, 地址减小方向(反向) • ②设置源串地址 • 将源串首地址(DF=0),或末地址(DF=1)放入 DS、SI中。 • ③设置目的串地址 • 将目的串首地址(DF=0),或末地址(DF=1)放入 ES、DI中。 • ④设置串长度 • 将串的长度(传送次数)放入CX中。 • ⑤字节传送用 REP MOVSB • 字传送用 REP MOVSW
例1 编程将存放在 str1中的4字节字符串传送到str2定义的缓冲区中。 str1 ‘A’ ‘B’ ‘C’ ‘D’ str2
data1 SEGMENT • str1 DB ‘ABCD’;源串 • data1 ENDS • data2 SEGMENT • str2 DB 4 DUP(?) ;缓冲区 • data2 ENDS • code SEGMENT • 、、、、、、 • CLD ;DF=0,正方向传送 • MOV AX,data1 ;源串首地址的段值→ DS • MOV DS,AX • LEA SI,str1 ;源串首地址的偏值→ SI • MOV AX,data2 ;目的串首地址的段值→ ES • MOV ES,AX • LEA DI,str2 ;目的串首地址的偏值→ DI • MOV CX, 4 ;串长度 CX • REP MOVSB;串传送 • 、、、、、、 • code ENDS
假设程序经汇编、连接后,装入内存的情况如下:假设程序经汇编、连接后,装入内存的情况如下: • data1 SEGMENT • str1 DB ‘ABCD’ • data1 ENDS • data2 SEGMENT • str2 DB 4 DUP(?) • data2 EMDS • code SEGMENT • 、、、、、、 • CLD • MOV AX,data1 • MOV DS,AX • LEA SI,str1 • MOV AX,data2 • MOV ES,AX • LEA DI,str2 • MOV CX, 4 • REP MOVSB • 、、、、、、 • code ENDS
用REPZ CMPS进行串比较 编程: ① 设置比较方向 (STD或CLD) ② 设置源串、目的串地址 将源串首地址(DF=0时),或末地址(DF=1时)放入 DS、SI 将目的串首地址(DF=0时),或末地址(DF=1时)放入ES、DI ③ 设置串长度 将串的长度放入CX中 ④ 按字节比较用 REPZ CMPSB 按字比较用 REPZ CMPSW
执行完REPZ CMPS后,根据ZF判断两串比较结果。 • 若ZF=1, 两串相等,此时: • CX=0, 表明串中所有元素已比较完毕 • SI、DI指向串尾的下一单元。 • 若ZF=0, 两串不等,此时: • CX的值为剩下的未比较的元素个数。 • SI、DI指向不相等元素的下一元素。
code SEGMENT • 、、、、、、 • CLD ;DF=0,正向比较 • MOV AX,SEG string1 ;源串首地址→ DS:SI • MOV DS,AX • LEA SI,string1 • MOV AX,SEG string2 ;目的串首地址→ ES:DI • MOV ES,AX • LEA DI,string2 • MOV CX, 8 ;串长度→ CX • REPZ CMPSB;串比较 • JZ equal ;利用ZF判断比较结果 • 不相等处理 • JMP exit • equal: 相等处理 • exit: 、、、 • code ENDS
code SEGMENT • 、、、、、、 • CLD ;DF=0,正向比较 • MOV AX,SEG string1 ;源串首地址→ DS:SI • MOV DS,AX • LEA SI,string1 • MOV AX,SEG string2 ;目的串首地址→ ES:DI • MOV ES,AX • LEA DI,string2 • MOV CX, 8 ;串长度→ CX • REPZ CMPSB • JZ equal • 不相等处理 • JMP exit • equal: 相等处理 • exit: 、、、 • code ENDS JNZ notequ 相等处理 JMP exit notequ: 不相等处理 exit: 、、、
例 执行完REPZ CMPSB后,此时: ZF=1, 两串相等 CX=0 , 两串所有元素已比较完 SI、DI串尾的下一单元
例 执行完REPZ CMPSB后,此时: ZF=0, 两串不等 CX=3,剩下的未比较的元素个数 SI、DI指向不相等元素的下一元素。
例3 用REPNZ SCAS 在串中找关键字。 编程步骤: ①设置查找方向 ②设置串地址 将串的首地址(DF=0时),或末地址(DF=1时)放入ES、DI中。 ③设置关键字 将关键字放入AL (关键字为字节)或 放入AX(关键字为字)。 ④设置串长度 将串的长度放入CX中。 ⑤查找字节用 REPNZ SCASB 查找字用 REPNZ SCASW
执行完REPNZ SCAS后,根据ZF判断查找结果。 • 若 ZF=1, 则串中有关键字,此时: • CX的值为剩下的未搜索的元素个数, • DI指向关键字元素的下一元素, • 而关键字在( DI )-1的位置 • 若 ZF=0, 则串中无关键字,此时: • CX=0,表明串中所有元素以搜索完毕 • DI指向串尾的下一单元。