目录
一、实验目的
1、学习DOS及BIOS中断调用方法。
2、巩固子程序(过程)设计、分支和循环结构程序设计的方法。
二、实验内容
第一题
1、在数据段中有个字节数据变量NUM,编程将NUM中的数(如3F H)以16进制的形式在显示器上用彩色字体显示出来(即显示出3F这4个字符)。
要求:将数值转换为ASCII码的程序设计为子程序。主程序、及子程序,各画一个流程图。
流程图
代码
DATA SEGMENT
NUM DB 3FH ;定义一个字节数据变量NUM
DATA ENDS
CODE SEGMENT
ASSUME CS:CODE, DS:DATA
START:
MOV AX, DATA
MOV DS, AX ;数据段地址放入寄存器DS
MOV AL, NUM ;将NUM中的数复制到AL中
SHR AL, 4 ;右移4位,得到高4位
CALL TO_ASCII ;调用子程序,将AL中数转换为ASCII码
MOV AH, 09H ;功能号
MOV BH, 0H ;设置页号
MOV BL, 0EH ;设置颜色属性(黄色前景,黑色背景)
MOV CX, 1 ;设置重复次数
INT 10H ;调用BIOS中断,打印彩色字符
MOV AL, NUM
AND AL, 0FH ;与0FH,得到低4位
CALL TO_ASCII ;调用子程序,将NUM转换为ASCII码
MOV AH, 02H
MOV DH, 0H ;设置行号
MOV DL, 1H ;设置列号
INT 10H ;调用BIOS中断,设置光标位置
MOV AH, 09H
INT 10H ;调用BIOS中断,打印彩色字符
MOV AH, 4CH ;返回DOS
INT 21H
TO_ASCII PROC ;定义子程序
CMP AL, 9 ;比较是否小于等于9
JBE LESS_NINE ;如果是,则跳转
ADD AL, 7 ;如果不是,则加7,得到A~F对应的ASCII码
LESS_NINE: ADD AL, 30H ;加30H,得到0~9对应的ASCII码
RET ;返回主程序
TO_ASCII ENDP ;结束子程序
CODE ENDS ;结束代码段
END START ;结束程序
程序编译信息截图
程序运行结果截图
第二题
2、每次从键盘输入一个大写字母,并将其转换为相应的小写字母输出到屏幕上显示,然后继续输入下一个字母;此转换一直进行到输入“#”号为止;若输入过程中输入了除大写字母和“#”以外的其他字符,则在屏幕上给出错误提示信息:“ERROR!”,并继续进行下一个大写字母的输入。
流程图
代码
DATA SEGMENT
ERR DB 'ERROR!$' ;定义一个错误提示信息
DATA ENDS
STACK SEGMENT
STACK ENDS
CODE SEGMENT
ASSUME CS:CODE, DS:DATA, SS:STACK
START:
MOV AX, DATA ;初始化数据段寄存器
MOV DS, AX
MOV CX, 6H
NEXT: MOV AH, 08H ;设置DOS功能调用参数
INT 21H ;调用DOS中断,从键盘输入一个字符到AL中
CMP AL, '#' ;比较是否输入了'#'号
JE FINISH ;如果是,跳转到结束
CMP AL, 'A' ;比较是否输入了大写字母
JB ERROR ;如果小于'A',跳转到ERROR标签处
CMP AL, 'Z' ;比较是否输入了大写字母
JA ERROR ;如果大于'Z',跳转到ERROR标签处
ADD AL, 20H ;将大写字母转换为小写字母
MOV DL, AL
MOV AH, 02H ;设置DOS功能调用参数
INT 21H ;调用DOS中断,将AL中的字符输出到屏幕上
JMP NEXT ;跳转到NEXT标签处,继续输入下一个字符
ERROR:
MOV AH, 9H ;设置DOS功能调用参数
MOV BL, 0CEH
INT 10H
MOV DX, OFFSET ERR ;将错误提示信息的偏移地址存入DX寄存器
INT 21H ;调用DOS中断,将DX指向的字符串输出到屏幕上
JMP NEXT ;跳转到NEXT标签处,继续输入下一个字符
FINISH: MOV AH, 4CH ;返回DOS
INT 21H
CODE ENDS ;结束代码段
END START ;结束程序
程序运行结果截图
实验调试过程记录、结果分析及评价
可以看到,这个代码其实是最简单的,这是优点,但是它很大程度破坏了输出的连贯性,每输入错误一个,就会打印ERROR所以我下面做了一个plus版的代码,感兴趣的可以继续往下看一看。
进阶版:
ERROR提示不会打断输入:将第一行留出来,如果输入不符合要求,则提示黄字红底的ERROR,直到下一个输入符正确,则提示消失:
代码
DATA SEGMENT
ERR DB 'ERROR!$' ;定义一个错误提示信息
DATA ENDS
STACK SEGMENT
STACK ENDS
CODE SEGMENT
ASSUME CS:CODE, DS:DATA, SS:STACK
START:
MOV AX, DATA ;初始化数据段寄存器
MOV DS, AX
MOV DX, 0100H
MOV AH, 02H
INT 10H ;将光标位置设置在1行0列
NEXT: MOV AH, 08H ;设置DOS功能调用参数
INT 21H ;调用DOS中断,从键盘输入一个字符到AL中
CMP AL, '#' ;比较是否输入了'#'号
JE FINISH ;如果是,跳转到结束
CMP AL, 'A' ;比较是否输入了大写字母
JB ERROR ;如果小于'A',跳转到ERROR标签处
CMP AL, 'Z' ;比较是否输入了大写字母
JA ERROR ;如果大于'Z',跳转到ERROR标签处
CMP BL, 0CEH ;如果上一个输入错误字符则BL=0CEH
JNE PRINT ;没有错误提示不用清除
CALL CLEAN ;否则调用子程序清除错误提示
PRINT: ADD AL, 20H ;将大写字母转换为小写字母
MOV DL, AL
MOV AH, 02H ;设置DOS功能调用参数
INT 21H ;调用DOS中断,将AL中的字符输出到屏幕上
JMP NEXT ;跳转到NEXT标签处,继续输入下一个字符
ERROR:
CMP BL, 0CEH ;如果重复出错,不重复提示
JE NEXT
MOV AH, 03H
INT 10H ;获取当前光标位置
PUSH DX ;保护当前光标位置
MOV DX, 0H
MOV AH, 02H
INT 10H ;光标定位到0行0列
MOV AH, 9H ;设置DOS功能调用参数
MOV CX, 6H
MOV BL, 0CEH
INT 10H
MOV DX, OFFSET ERR ;将错误提示信息的偏移地址存入DX寄存器
INT 21H ;调用DOS中断,将DX指向的字符串输出到屏幕上
POP DX
MOV AH, 02H
INT 10H ;还原光标位置
JMP NEXT ;跳转到NEXT标签处,继续输入下一个字符
CLEAN PROC
MOV AH, 03H
INT 10H ;获取当前光标位置
PUSH DX ;保护当前光标位置
MOV DX, 0H
MOV AH, 02H
INT 10H ;光标定位到0行0列
MOV BL, 0H
MOV AH, 9H
MOV CX, 6H
INT 10H ;清除ERROR
POP DX
MOV AH, 02H
INT 10H
MOV AH, 02H ;还原光标位置
RET ;退出子程序
CLEAN ENDP
FINISH: MOV AH, 4CH ;返回DOS
INT 21H
CODE ENDS ;结束代码段
END START ;结束程序
程序运行结果:
可以看到,我程序运行错误会提示,但是如果继续正确,则提示会消失 ,非常显眼,还不会像第一种一样输入错误会破坏整体的输入。