第三章 16位和32位微处理器的指令系统3.3-3.6

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

DL ← DL+30H 完成数值0~9的ASCII码转换
DL 超出39H?
N
DL←DL+07H 完成数值A~F的ASCII码转换 用02功能显示DL中的字符
Y
N
CH ←CH-1转换结束? RET返回
Y
list_bx PROC MOV CH, 4 MOV CL, 4 next: ROL BX, CL MOV DL, BL AND DL, 0FH ADD DL, 30H CMP DL, 39H JLE print ADD DL, 07H print: MOV AH, 2H INT 21H DEC CH JNZ next RET ;子程返回 list_bx ENDP
清ASCII码的高4位可得各数位大小值。
01h 02h 03h 04h
?
04D2h
01h
02h
03h
04h
?
04D2h
算法一: 数值大小 = 各位值×权值之和
1234D = 千位×1000 + 百位×100 + 十位×10 + 个位
= 1×1000 + 2×100 + 3×10 + 4 = 0000 0100 1101 0010B = 04D2H
;显示AX ;显示BX ;显示CX MOV BX, DS ;显示DS CALL listbx MOV BX, ES ;显示ES CALL listbx MOV BX, SS ;显示SS CALL listbx MOV BX, SEG start CALL listbx ;显示CS MOV BX, OFFSET start CALL listbx ;显示IP PUSHF POP BX ;显示PSW CALL listbx MOV AH, 4CH ;返回DOS INT 21H
N
CX ← CX-1 CX=0? Y BX←转换结果AX RET返回
change子程序流程图
1234D = ( ( ( 0×10 + 1 ) ×10 + 2 ) ×10 + 3 ) ×10 + 4
显示字符个数CH=4 循环移位次数CL=4 BX循环左移4位,将要显示的值 移至低4位,保存在DL中 清DL 的高4位, 只保留要显示位的值
;显示DX
;显示SP ;显示BP ;显示SI ;显示DI
listbx PROC PUSH CX ;保存寄存器 PUSH BX PUSH DX PUSH AX listbx PROC PUSHF MOV CH, 4 MOV CL, 4 next: ROL BX, CL MOV DL, BL AND DL, 0FH ADD DL, 30H CMP DL, 39H JLE print ADD DL,07H print: MOV AH,2H INT 21H DEC CH JNZ next
2) 对于1010~1111(A~F), 先扩展成一个字节,高4位清0,
加上30H后, 还要再加上07H,才能得到’A’~’F’ 对应的ASCII 码 0000 1010B+30H+07H = 41H 1010B ‘A’ 0000 1111B+30H+07H =46H 1111B ‘F’
开始 显示字符个数CH=4 循环移位次数CL=4
06 04 31 32 33 34 0D 00 00 00 num
SI ← 数据串偏址 CX ← 数据串长度 AX ← 部分和初值0 DI ← 乘数10 AX←部分和乘10 (BX) ← 输入字符的数值大小 (AX) ← (AX)+(BX) 形成新的部分和 修改SI指针, 指向下一位输入
06 04 31 32 33 34 0D 00 00 00 num
code SEGMENT ASSUME CS:code start: MOV CH, 4 ;字符个数 MOV CL, 4 ;循环移位次数 next: ROL BX, CL ;取显示位的值 MOV DL, BL ;保存在DL中 AND DL, 0FH ;清除高4位 ADD DL, 30H ;转变为数字的ASCII CMP DL, 39H ;大于39H, 则应转变 JLE print ;为字母A~F的ASCII ADD DL, 07H print: MOV AH, 2H ;显示DL中的字符 INT 21H DEC CH ;显示结束? JNZ next MOV AH, 4CH ;返回DOS INT 21H code ENDS END start
AX=0000 BX=0000 CX=007B DX=0000 SP=0000 BP=0000 SI=0000 DI=0000 DS=128E ES=128E SS=129E CS=129E IP=0000 NV UP EI PL NZ NA PO NC 129E:0000 53 PUSH BX
-G Program terminated normally -
code ENDS
list_bx子程序流程图
END
start
例2 程序存在的问题: 1.未处理输入非数字字符的情况 2.输入的十进制数范围为0~65535 3.当输入字符个数为0(直接回车)时,结果错误 4.未处理负数情况 5.结果的显示未换行 Input:1234 最后看到的是: 0D42t: 1234
SS:SP 执行push 后
SS:SP 执行call 后 SS:SP 执行call 前
(AX)
(IP) SS:SP 执行ret 后
input
(IP)
input code

下面程序段,思考是否可以完成 AX→ CX, BX→DX
CODE SEGMENT ASSUME CS:code start: MOV AX,data MOV DS,AX PUSH AX PUSH BX CALL sub MOV AH, 4CH INT 21H sub PROC POP DX POP CX 、、 、、 RET sub ENDP code ENDS END start
change PROC LEA MOV MOV MOV MOV next: MUL MOV MOV AND ADD INC LOOP zero: MOV RET change ENDP SI, num+2 CL, num+1 CH, 0 AX, 0 DI, 10 DI BH, 0 BL, [SI] BL, 0FH AX, BX SI next BX, AX
data num data
SEGMENT DB 6, ?, 6 DUP(?) ENDS ASSUME CS:code, DS:data
string DB ‘Input:’,’$’
CODE SEGMENT
start: MOV AX, data MOV DS, AX CALL input CALL change CALL list_bx MOV AH, 4CH INT 21H
;; 子程返回 恢复寄存器
;子程序返回
D:\>LIST_REG
D:\ >DEBUG LIST_REG.EXE
;在DOS下执行程序
;利用DEBUG检测结果
0000 0000 00FF 0BDF 0000 0912 0000 0000 0BDF 0BDF 0BEF 0BEF 0000 3202
-R
;显示当前寄存器内容
BX循环左移4位,将要显示的 值移至低4位,保存在DL中 清DL 的高4位, 只保留要显示位的值 DL ← DL+30H 完成数值0~9的ASCII码转换 DL 超 出 39H ? N Y DL←DL+07H 完成数值A~F的ASCII码转换 用02功能显示DL中的字符 N CH ←CH-1转换结束? Y 返回DOS
;执行程序
0000 0000 007B 0000 0000 0000 0000 0000 128E 128E 129E 129E 0000 7202
运行的结果与用R命令显示的结果相同, 程序运行结果正确
例2 将键盘输入的十进制数据串转换成相应大小的十六进
制数值存放在BX寄存器中。 分析: 从键盘输入’1234’ ( 表示1234 ) 用0AH功能输入, 则缓冲区存放的内容为: 06h 04h 31h 32h 33h 34h 0Dh num 问题:要转换成1234 即 04D2h存放在BX中, 怎么实现?
用十六进制显示 BX内容子程 序
MOV DL, 20H MOV AH, 02H INT 21H RET POPF listbx ENDP POP AX code POP ENDS DX END start POP BX POP CX RET listbx ENDP code ENDS END start ;显示空格符
例1
将BX寄存器中的内容以十六进制形式显示出来。 ▲ BX是一个16位寄存器 二进制 1010 1001 0011 1110 十六进制 A 9 3 E 屏幕上的显示 ‘A’ ‘9’ ‘3’ ‘E’ 对应的ASCII 41H 39H 33H 45H
?
▲ 用十六进制显示时,每4位用一个字符显示,共4个 其中 0000 →’0’ 30H , 1010 →’A’ 41H 0001 →’1’ 31H , 1011 →’B’ 42H 、、 、、 1001 →’9’ 39H , 1111 →’F’ 46H
▲ 将上例改写为一个子程序,入口参数为BX
▲ 子程序中注意寄存器值的保存和恢复
▲ 注意CS 、IP、PSW寄存器值的获取方法
例 将CPU内14个16位寄存器当前内容分别用16进制形式显示出来
(采用DEBUG下R命令的显示顺序)
code SEGMENT ASSUME CS:code start: PUSH BX MOV BX, AX CALL listbx POP BX CALL listbx MOV BX, CX CALL listbx MOV BX, DX CALL listbx MOV BX, SP CALL listbx MOV BX, BP CALL listbx MOV BX, SI CALL listbx MOV BX, DI CALL listbx
算法: 取出要显示的某4位,转换为对应的ASCII码, 再调用DOS系统功能进行显示。 1) 对于0000~1001(0~9), 先扩展成一个字节,高4位清0, 加上30H后, 即可得字符’0’~’9’对应的ASCII码。 0000 0001B + 30H= 31H 0000 1001B + 30H=39H 0001B ‘1’ 1001B ‘9’
思考:
1. 例1采用的是大写字母A~F进行显示, 若采用小写字符a ~ f 进行显示,程序如何改写? 1010 0011 1001 1110 ‘A39E’ 或 ‘a39e’ 2. 编程将 CPU 内 14个 16位寄存器当前的内容 分别用十六进制形式显示出来。
编程将CPU内14个16位寄存器当前的内容 分别用十六进制形式显示出来。 要点:
编写子程序的注意事项: 注意子程序中PUSH、POP应成对,否则易造成死机。
data string data code start: SEGMENT DB ‘Hello’,’$’ ENDS SEGMENT ASSUME CS:code, DS:data MOV AX, data MOV DS, AX CALL input MOV AH, 4CH INT 21H PROC PUSH AX LEA DX, string MOV AH, 09H INT 21H RET ENDP ENDS END start
主程序流程图
ຫໍສະໝຸດ Baidu
调用09功能 显示输入提示
调用0A 功能 等待从键盘输入数据 RET返回 input 子程序流程图
input PROC LEA MOV INT LEA MOV INT RET input ENDP
DX , string AH , 09H 21H DX , num AH , 0AH 21H
01h
02h
03h
04h
?
04D2h
算法二:
数值大小 =部分和×10 +下一位数值
1234D = ( ( ( 0×10 + 1 ) ×10 + 2 ) ×10 + 3 ) ×10 + 4 = 0000 0100 1101 0010B = 04D2H
部分和从0开始,循环次数等于输入的位数
开始 初始化DS的值 CALL input 显示输入提示,等待 从键盘输入十进制数据串 CALL change 将数据串转化为 相应的数值存放在BX中 CALL list_bx 将BX内容以16 进制显示出来 返回DOS
相关文档
最新文档