当前位置:文档之家› 第三章 16位和32位微处理器的指令系统3.3-3.6

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


;显示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
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
code ENDS
list_bx子程序流程图
ENDቤተ መጻሕፍቲ ባይዱ
start
例2 程序存在的问题: 1.未处理输入非数字字符的情况 2.输入的十进制数范围为0~65535 3.当输入字符个数为0(直接回车)时,结果错误 4.未处理负数情况 5.结果的显示未换行 Input:1234 最后看到的是: 0D42t: 1234
思考:
1. 例1采用的是大写字母A~F进行显示, 若采用小写字符a ~ f 进行显示,程序如何改写? 1010 0011 1001 1110 ‘A39E’ 或 ‘a39e’ 2. 编程将 CPU 内 14个 16位寄存器当前的内容 分别用十六进制形式显示出来。
编程将CPU内14个16位寄存器当前的内容 分别用十六进制形式显示出来。 要点:
用十六进制显示 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 ;显示空格符
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
算法: 取出要显示的某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’
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
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
;执行程序
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中, 怎么实现?
清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
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位, 只保留要显示位的值
主程序流程图
调用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
▲ 将上例改写为一个子程序,入口参数为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
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
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
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 -
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
;显示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
相关主题