- 2021-11-23 发布 |
- 37.5 KB |
- 41页
申明敬告: 本站不保证该用户上传的文档完整性,不预览、不比对内容而直接下载产生的反悔问题本站不予受理。
文档介绍
带进位位的加法指令
1 3.3.3 逻辑运算和移位指令 逻辑运算指令 ( 与 / 或 / 异或 / 非 ) ● 运算规则:按位操作,无进 / 借位 ● 对标志位的影响 ( 除 NOT 指令外 ) : CF OF SF ZF PF AF 0 0 * * * 无定义 根据运算结果设置 注意 : 非指令 NOT 对标志无影响 2 表 4 – 3 逻辑运算类指令 3 (1) 逻辑 ” 与 ” AND 对两个操作数进行按位逻辑 “ 与 ” 操作。 格式: AND dest, src 用途: 保留操作数的某几位,清零其他位 。 例 1 : 保留 AL 中低4位,高 4 位清 0 。 AND AL, 0FH 例 2 : AL 中有字符 ’ a ’ ~ ’ z ’ , 将其转换成大写。 AND AL, 01011111B 4 例 3 : 测试 AL 的 bit7,bit5,bit2 是否都是 1 。 AND AL, 10100100B CMP AL, 10100100B JZ YES ; if match, go to YES … … ; if not match … … YES: … … ; goes here if all ‘ 1 ’ 5 对两个操作数进行按位逻辑 ” 或 ” 操作。 格式: OR dest, src 用途: 对操作数的某几位置 1 ; 对两操作数进行组合 。 例 1 : 把 AL 中的非压缩 BCD 码变成相应十进制 数的 ASCII 码。 OR AL, 30H (2) 逻辑 ” 或 ” OR 6 例 2 : 把 AH 和 AL 中的非压缩 BCD 码组合成压 缩的 BCD 码 , 放到 AL 中。 MOV CL, 4 SHL AH, CL OR AL, AH 例 3 : 把 AL 的第 5 位置为 1 OR AL, 00100000B 7 对操作数进行按位逻辑 ” 非 ” 操作。 格式 : NOT mem/reg 例: NOT CX NOT BYTE PTR[DI] (3) 逻辑 “ 非 ” ( 取反 ) NOT 8 对两个操作数按位进行 ” 异或 ” 操作。 格式: XOR dest, src 用途: 对 reg 清零 ( 自身异或 ) 把 reg/mem 的某几位变反 ( 与 ’ 1 ’ 异或 ) 例 1 : 把 AX 寄存器清零。 例 2 : 把 DH 的 bit4,3 变反 ① MOV AX,0 XOR DH,18H ② XOR AX,AX ③ AND AX,0 ④ SUB AX,AX (4) 逻辑 ” 异或 ” XOR 9 操作 与 AND 指令类似 ,但不将 ” 与 ” 的结果送回,只影响标志位。 AND 与 TEST 间的区别类似于 SUB 与 CMP 间的区别 作用 : TEST 指令常用于位测试,与条件转移指令一起用。 例: 测试 AL 的内容是否为负数。 TEST AL,80H ; 检查 AL 中 D 7 =1? JNZ MINUS ; 是1 ( 负数 ) ,转 MINUS … … ; 否则 ( 正数 ) 不转移 MINUS: … … … … (5) 测试指令 TEST 10 表 4-4 移位操作类指令 2 . 移位指令 11 移位指令 功能示意 算术左移指令 算术右移指令 逻辑左移指令 逻辑右移指令 小循环右移指令 小循环左移指令 大循环左移指令 大循环右移指令 CF= 12 2 . 移位指令 ( 1 ) 非循环移位指令 算术左移指令 SAL ( Shift Arithmetic Left ) 算术右移指令 SAR ( Shift Arithmetic Right ) 逻辑左移指令 SHL ( Shift Left ) 逻辑右移指令 SHR ( Shift Right ) 这4条指令的格式相同,以 SAL 为例: SAL mem/reg, CL ; 移位位数 >1 时 1 ; 移位位数 =1 时 13 移位指令 执行的操作如下图所示: 最低位 最高位 CF 0 ( a) 算术 / 逻辑左移 SAL/SHL 最低位 最高位 CF ( b) 算术右移 SAR 最低位 最高位 CF ( c) 逻辑右移 SHR 0 非循环 移位指令 功能示意图 14 算术移位 —— 把操作数看做 有符号数 ; 逻辑移位 —— 把操作数看做 无符号数 。 移位位数 : 一般 放在 CL 寄存器中, 但 如果只移1位,也可以直接写在指令中。 例如: MOV CL,4 SHR AL,CL ;AL 中的内容右移 4 位 对 Flags 影响 : 影响 CF,PF,SF,ZF,OF 标志。 移位效果 : 结果未溢出时: 左移 1 位 ≡ 操作数 × 2 右移 1 位 ≡ 操作数 2 15 例: 把 AL 中的数 x × 10 因为 10=8+2=2 3 +2 1 ,所以可用移位实现乘 10 操作。程序如下: SAL AL,1 ; 2 x MOV AH,AL SAL AL,1 ; 4 x SAL AL,1 ; 8 x ADD AL,AH ; 8 x + 2 x = 10 x 16 不含 CF 的 ( 小 ) 循环左移指令 ROL 不含 CF 的 ( 小 ) 循环右移指令 ROR 含 CF 的 ( 大 ) 循环左移指令 RCL 含 CF 的 ( 大 ) 循环右移指令 RCR 格式 同非循环移位指令。 移位位数 一般 放在 CL 寄存器中 但 如果只移1位,也可直接写在指令中。 对 Flags 的影响 : 只影响标志位 CF 和 OF 。 (2)循环移位指令 17 这4条指令的功能如下图示: 最低位 最高位 CF ( a) ROL 最低位 最高位 CF ( c) RCL 最低位 最高位 CF ( b) ROR 最低位 最高位 CF ( d) RCR 循环移位指令功能示意图 18 用 移位操作 代替 乘除法 可提高运算速度 例: 前例中计算 x ×10 。 (1) 采用乘法指令: MOV BL,10 MUL BL 共需70~77个 T 周期。 (2) 采用移位和加法指令: SAL AL,1 ; 2T MOV AH,AL ; 2T SAL AL,1 ; 2T SAL AL,1 ; 2T ADD AL,AH ; 3T 只需1 1 个 T 周期 , 仅相当于乘法的 1/7 。 19 循环移位 举例: 例 1 : 将 AL 的 高 4 位 与 低 4 位 互换 。 MOV CL,4 ROL AL,CL 例 2 : 将 1A00H 内存单元中的 双字 (32 位 ) 循环左移 1 位。 CMP [1A00H],8000H CMC RCL WORD PTR[1A02H],1 RCL WORD PTR[1A00H],1 20 例: 设在1000 H 开始存有四个 压缩的 BCD 码 12、34、56、78。要求把它们转换为 ASCII 码 存放在3000 H 开始的单元中。 假定 DS 、 ES 都已设置为 数据段的段基址。 程序见下页。 1000 H 3000 H 12 34 56 78 3 2 H 3 1 H 3 4 H 3 3 H 3 6 H 3 5 H 3 8 H 3 7 H SI= DI= BX=4 21 MOV SI,1000H ;SI←BCD 首址 MOV DI,3000H ;DI←ASCII 首址 MOV BX,4 ; 置计数器初值 BBB: MOV AL,[SI] ;AL←BCD 码,第一次取12 H AND AL,0FH ; 屏蔽高4位 →02H OR AL,30H ; 转换为 ASCII 码 → 32 H STOSB ; 保存结果 , 等价 MOV[DI] , AL INC DI LODSB ; MOV AL , [SI] INC SI MOV CL,4 SHR AL,CL ; 逻辑右移4位 OR AL,30H ; 得到高4位 ASCII 码 STOSB ;保存结果 , 等价 MOV[DI] , AL INC DI DEC BX ;(BX)←(BX)-1 JNZ BBB ;(BX)≠0 ,则继续循环 22 作业 P152-P153 3.1 、 3.2 、 3.7 、 3.9 、 3.13 、 3.16 23 3.3.4 串操作指令 串 :顺序放在内存中的一组相同类型的数据。 串操作 : 对串中的元素进行相同的操作。 串操作的寻址方式 : 源操作数指针 —— DS:SI (DS 可超越 ) 目的操作数指针 —— ES:DI 数据块长度 —— CX 功能 : 可完成两个存储单元之间的传送 MOVS 、比较 CMPS 、搜索 SANS 、读 LODS 、写 STOS 5 种操作(也仅是串指令可以)。 一次操作对象为 16 位 ( W )或 8 位 ( B )数据, 但为 下一次 操作做了准备 。 24 串操作指令 执行动作示意图 自动循环 - 加前缀 REP REPE/REPZ REPNE/REPNZ (a) 方向标志 DF=0 (b) 方向标志位 DF=1 25 每次串操作后( 辅助动作 ) : 串操作指令自动修改 SI 和 DI —— 字节 ±1 ,字 ±2 。 DF 标志决定 ±, DF=0 增地址方向; DF=1 减地址方向。 ( 注意 :退出串操作后,指针指向最后操作的元素的下一个元素 ) 重复前缀 有的串操作指令前面可加上 重复前缀 REP 。 当使用 REP 前缀时, 该指令重复执行, 重复执行次数由 CX 决定(带有 REP 前缀的 串操作指令每执行一次, CX 自动减 1 )。 重复前缀 包括: REP CX≠0 时重复执行 REP E /REP Z CX≠0∧ZF=1 时重复执行 REP NE /REP NZ CX≠0∧ZF=0 时重复执行 26 表 4 – 5 串操作指令 27 串指令 使用 的一般 方法 : 设置源串地址 设置目标串地址 设置串长度 设置操作方向 DF 串指令 MOV SI, 源串首地址 (或 LEA SI, 源串 ) MOV DI, 目的串首地址 (或 LEA DI, 目的串 ) MOV CX, 串长度 CLD (或 STD ) 串指令 注意 : DS 与 ES 一般在完整程序的开始处设置 , 在此串指令的程序段中不必重复设置 28 指令执行的操作为: MOVS B : ES:[DI]←DS:[SI] SI←SI ±1, D I← DI ±1 MOVS W : ES:[DI+1][DI]←DS:[SI+1][SI] SI← SI ±2, D I← DI ±2 指令也可写成: MOVS dest,src ( 即无 B 或 W 标识) 但要求: ① src 用 DS:SI 寻址 , d est 用 ES:DI 寻址 ② 传送是字节还是字,由操作数的类型决定 ⒈串传送指令 MOVS B / MOVS W 29 串传送指令 使用举例 用串传送指令实现200个字节的数据传送: LEA SI,MEM1 LEA DI,MEM2 MOV CX,200 CLD REP MOVS B HLT 30 ⒉串比较指令 CMPS B / CMPS W 指令执行的操作为: CMPSB : ES:[DI] - DS:[SI] SI←SI±1, DI← DI±1 CMPSW : ES:[DI+1][DI] - DS:[SI+1][SI] SI← SI±2, DI← DI±2 比较的结果只反映在标志位上,串本身无变化。 本指令可用来检查两个串是否相等。 格式: CMPS OPRD1 , OPRD2 CMPS B CMPS W 31 串比较指令 举例 JZ STOP DEC SI MOV AL , [SI] MOV BX , SI STOP : HLT 测试内存中两块 200 个字节数据是否相同 , 并找出第一个不相等字符的地址 , 将该地址和字符存贮起来。 LEA SI , MEM1 LEA DI , MEM2 MOV CX , 200 CLD REPE CMPS B 32 ⒊串扫描 SCAS B / SCAS W 执行的操作: 对字节: AL - ES:[DI] DI DI±1 对字: AX - ES:[DI + 1][DI] DI DI±2 搜索指令执行的仍是比较(减法)操作,结果只影响标志位。 要搜索的关键字放在 AL( 字节)或 AX( 字)中。 本指令用于在串中查找指定的信息。 格式: SCAS OPRD SCAS B SCAS W 33 SCAS 指令加上重复前缀后 , 可对串 进行连续扫描比较: 若前缀为 REP Z ,则表示 比较结果相等且( ZF=1) 且串未结束( CX≠0), 则继续比较。 若前缀为 REP NZ ,则表示比较结果不相等( ZF=0) 且串未结束( CX≠0) 就继续比较。 34 例: 在 ES 段的偏移1000 H 开始处存有10个 ASCII 码。搜索 ’ E ’ ,若找到则记下搜索次数及存放地址,并在屏幕上显示 ’ Y ’ ;若未找到则显示 ’ N ’ 。( 见右图 ) 在屏幕上显示一个字符的 指令段如下: (参见附录 C.3 DOS 功能调用 ) MOV DL,< 字符 > MOV AH,2 INT 21H 实现题目要求的程序段见下页: 1000 H 41 42 43 44 45 46 ’ A ’ ’ B ’ ’ C ’ ’ D ’ ’ F ’ . . . ES 段 ’ E ’ 35 MOV DI, 1000H ;(DI)← 串偏移地址 MOV CX, 0AH ;(CX)← 串长度 MOV AL, ’ E ’ ; 搜索关键字 = ’ E ’ CLD ; 从低地址到高地址进行搜索 REP NZ SCAS B ; 若未找到, 继续搜索 JZ FOUND ; 找到, 转至 FOUND MOV DL, ’ N ’ ; 串中无 ’ E ’ , (DL)← ’ N ’ JMP DONE ; 转至 DONE FOUND:DEC DI ; 指针回退 MOV ADDR, DI ;ADDR← ’ E ’ 的地址 SUB DI, 1000H MOV NUM, DI ;NUM← 搜索次数 MOV DL, ’ Y ’ ;(DL)← ’ Y ’ DONE: MOV AH, 2 INT 21H ;显示字符 HLT 36 执行的操作为: 对字节: AL←DS:[SI] SI←SI ±1 对字: AX←DS:[SI+1][SI] SI←SI ±2 串装入指令通常不加重复前缀。 LODS B 等价于 : LODS W 等价于 : MOV AL,[SI ] MOV AX,[SI] INC SI INC SI INC SI ⒋串装入指令 LODS B / LODS W 格式: LODS OPRD LODS B LODS W 37 3 6 H 3 2 H 3 9 H 3 1 H STRING1 STRING2 3 8 H 3 5 H 3 6 H 3 3 H 被加数 加数 数据段 ‘8’ ‘5’ ‘6’ ‘2’ ‘9’ ‘1’ ‘6’ ‘3’ SUM 结果 ... ... 0 7 H 0 7 H 0 2 H 0 6 H 2658 3619 6277 LEA SI,STRING1 LEA DI,STRING2 LEA BX,SUM MOV CX,4 CLC AGAIN:MOV AL,[SI] ADC AL,[DI] AAA MOV [BX],AL INC SI INC DI INC BX DEC CX JNZ AGAIN 38 下面要求将两个 4 字节的 ASCII 码数据求和,并将和的结果送显示。 为此,要先化成 ASCII 码再送显示,程序段如下: LEA SI,SUM+3 ;(SI)←SUM+3 MOV CX,4 ;(CX)← 和长度 STD ; 置 DF=1, 减量修改 SI MOV AH,02 ;(AH)← 功能号 LP: LODS B ; 取 BCD 码至 AL, 且 SI←SI-1 ADD AL,30H ; 转换为 ASCII 码 MOV DL,AL ;(DL)← 字符 INT 21H ;显示字符 DEC CX JNZ LP …… 39 指令的操作为: 对字节: ES:[DI]←AL DI DI ±1 对字: ES:[DI+1][DI]←AX DI DI ±2 本指令用于把一块存储区域填充成某一初始值 ( 即对存储区进行初始化 ) 。 存储区域的首地址要预先设置到 ES:DI 中。 要存储到串中的数据要预先存到 AL(AX) 中。 ⒌串存储指令 STOS B / STOS W 格式: STOS OPRD STOS B STOS W 40 例 1 : 把从 A000H 开始的 2KB 内存单元清零。 程序段如下: MOV DI,0A000H MOV AX,0 MOV CX,1024 CLD REP STOS W 41 例 2 : 把1000 H 开始的100个存储单元填入 ASCII 码2 AH(*)。 程序段如下: MOV DI, 1000H ; 首地址 MOV AL, 2AH ;‘ *’= 2AH MOV CX, 100 ; 重复执行 100 次 CLD ; 增量修改 DI REP STOS B MOV DI , 1000H MOV CX , 64H MOV AL , 2AH AGAIN : MOV [DI] , AL INC DI DEC CX JNZ AGAIN HLT 请对比查看更多