微机原理 实验09:DOS及BIOS中断调用

目录

一、实验目的

二、实验内容

第一题

流程图

代码

程序编译信息截图

程序运行结果截图

第二题

流程图

代码

程序运行结果截图

实验调试过程记录、结果分析及评价

进阶版:

代码

程序运行结果:


一、实验目的

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               ;结束程序

程序运行结果:

 

可以看到,我程序运行错误会提示,但是如果继续正确,则提示会消失 ,非常显眼,还不会像第一种一样输入错误会破坏整体的输入。

  • 1
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Leisure_水中鱼

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值