【新书推荐】16.2 显示中断

2024-03-07 10:28
文章标签 显示 推荐 中断 新书 16.2

本文主要是介绍【新书推荐】16.2 显示中断,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

本节内容:屏幕显示的实现——显示I/O中断处理程序。显示器通过显示适配卡与系统相连,显示适配卡是显示输出的接口。早期显示适配卡是CGA和EGA等,目前常见的适配卡是VGA、TVGA、DVI、DP、Mini HDMI和Micro HDMI接口等。它们都支持两类显示方式:文本显示方式和图形显示方式,每一类显示方式含有多种显示模式。

文本显示方式:通常0~3号显示模式为文本显示方式,它们之间的区别是每屏可以显示的字符数和可使用的颜色数目不同。用的最普遍的是3号显示模式,本节以3号显示模式为代表做介绍。

显示属性:显示属性表示字符的文本颜色。8086计算机中,使用一个字显示字符,前一个字节为字符ASCII码,后一个字节为8位颜色属性。

显示存储区:8086计算机中,显示存储器为系统存储器的一部分,显存分为RAM和ROM两个部分,通常显示存储器安排的存储地址空间的段值为B800H或B000H。把将要输出的字符写入显存的RAM区域就可以在屏幕显示了。

显示I/O程序的功能和调用方法:参见表16-3。

举例:显示I/O程序的5号功能、0FH号功能、9号功能、6号功能。

示例代码:t16-2.asm~ t16-4.asm。

16.2.1 文本显示方式

文本显示方式是指以字符为单位显示的方式。字符通常是指字母、数字、普通符号(如运算符号)和一些特殊符号(如菱形块和矩形块)。通常0~3号显示模式为文本显示方式,它们之间的区别是每屏可以显示的字符数和可使用的颜色数目不同。用的最普遍的是3号显示模式,我们就以3号显示模式为代表做介绍。

3号文本显示模式

显示器的屏幕被划分为80列25行,随意每一屏最多显示2000(80*25)个字符。我们用行号和列号组成的坐标来定位屏幕上的每个可显示位置,左上角坐标规定为(0,0),向右增加列号,向下增加行号,右下角的坐标便是(79,24)。如图16-4所示。

                                图16-4 显示存储区与显示位置的对应关系

16.2.2 显示属性

屏幕上显示的字符取决于字符代码及字符属性。这里的属性指显示的颜色属性,规定了显示时的特性。

如图:16-5给出了显示时属性字节各位的定义。

在属性字节中,RGB分别表示红绿蓝,I表示亮度,BL表示闪烁。位0~3组合16种前景色,位4~6组合8种背景色。亮度和闪烁只能用于前景。I为1时表示高亮度,I为0时表示普通亮度。BL=1表示闪烁,BL=0不闪烁。

                图16-5 属性字节各位定义

表16-3列出了几种典型的属性值。当前景和背景相同时,字符就看不出了。

效果

BL  R  G  B  I  R  G  B

16进制值

黑底蓝字

0   0  0  0  0  0  0  1

01

黑底红字

0   0  0  0  0  1  0  0

04

黑底白字

0   0  0  0  0  1  1  1

07

黑底黄字

0   0  0  0  1  1  1  0

0E

黑底亮白字

0   0  0  0  1  1  1  1

0F

白底黑字

0   1  1  1  0  0  0  0

70

白底红字

0   1  1  1  0  1  0  0

74

黑底灰白闪烁字

1   0  0  0  0  1  1  1

87

白底红闪烁字

1   1  1  1  0  1  0  0

F4

                                                        表16-3 属性字的典型值

16.2.3 显示存储区

显示适配卡带有显示存储器RAM,用于存放屏幕上显示文本的ASCII码及属性。显示存储器RAM作为系统存储器的一部分,访问显示存储器与访问普通内存的方法一致。通常,显示存储器安排的存储地址空间的段值为B800H或B000H,对应的内存区域就称为显示存储区。我们假设段值是B800H。在3号文本显示模式下,屏幕上的每一个显示位置依次对应显示存储区中的两个字节单元,这种对应关系如图16-4所示。为了在屏幕上某个位置显示字符,只需要把显示字符的ASCII码及其属性填到显示存储区中对应存储单元即可。

举例

在屏幕的左上角以白底红字显示字符“B”:

……

MOV AX,B800H

MOV DS,AX

MOV BX,0

MOV AL,'B'

MOV AH,74H   ;白底红字

MOV [BX],AX

……

如果想了解屏幕上某个显示位置所显示的字符是什么,或显示的颜色是什么,只要从显示储存区中对应存储单元中取出字符的ASCII码和颜色属性即可。

举例

获取屏幕右下角所显示字符的ASCII码和颜色属性:

……

MOV AX,B800H

MOV DS,AX

MOV BX,(80*24+79)*2    ; .386模式下才可以这样写,8086需要分步计算表达式的值

MOV AX,[BX]

……

这种直接存取显示存储器进行显示的方法称为直接写屏。

例2:直接写屏

动手实验98采用直接写屏法在屏幕上用多种颜色属性显示字符串“HELLO”。

在理解下面示例程序的基础上,自己独立编写源程序。编译完成后,在debug调试器中单步跟踪调试,以验证程序的正确性。

算法分析:

第一步:先用一种属性在屏幕上显示指定信息;

第二步:在用户按键后,再换一种属性显示;

第三步:如果按ESC键,结束;

流程图:如图16-6所示。

        图16-6 直接写屏并指定颜色

示例代码73

;例2:采用直接写屏法在屏幕上用多种颜色属性显示字符串“WELOCME”

;先用一种属性在屏幕上显示指定信息,然后在用户按键后,再换一种属性显示,如果按ESC键,结束

;显示子程序ECHO采用了直接写屏方法实现。

;程序名:t16-2.asm

;=============================================================

assume cs:code,ds:data

;常量定义

row=5                ;显示信息的行号

colum=10          ;列号

esckey=1bh      ;ESC键的ASCII码值

;数据段

data segment

mess db ' WELOCME '               ;显示信息

mess_len=$-offset mess          ;显示信息的长度

colorb db 07h,17h,0fh,70h,74h        ;颜色

;colore与colorb存储地址不相同。如果前置则是别名,地址相同

colore label byte     

data ends

;代码段

code segment

start:

         mov ax,data

         mov ds,ax

         ;取颜色属性首地址

         mov di,offset colorb -1

nextc:

         inc di         ;调整指针

         cmp di,offset colore

         jnz nexte

         mov di,offset colorb

nexte:

         mov bl,[di]        ;取颜色

         ;参数

         mov si,offset mess

         mov cx,mess_len

         mov dh,row

         mov dl,colum

         ;显示字符串

         call echo

         ;接收键盘输入

         mov ah,0

         int 16h

         cmp al,esckey

         jnz nextc 

         mov ax,4c00h

         int 21h                                                          

;------------------------------------------------------

;子程序名:echo

;功能:直接写屏显示字符串

;入口参数:DS:SI=字符串首地址,

;CX=字符串长度,BL=属性,       

;DH显示开始行号,DL=显示开始列号                

;出口参数:无

echo proc

         mov ax,0b800h

         mov es,ax                                    

;设置显示开始位置的偏移,每屏80列25行

         mov al,80

         mul dh               ;偏移=(行号×80+列号)×2

         xor dh,dh

         add ax,dx ;ax+列号

         add ax,ax ;ax*2

         xchg ax,bx         ;偏移送入bx,属性送入ax          

         mov ah,al ;属性保存AH

         jcxz echo2         ;显示信息长度是否为0                

echo1:

         mov al,[si]         ;取一个要显示字符代码

         inc si

         mov es:[bx],ax ;送显示存储区,即显示

         inc bx

         inc bx

         loop echo1       ;循环显示       

echo2:

         ret

echo endp

code ends                                                                                                      

16.2.4 显示I/O程序的功能和调用方法

BIOS提供的显示I/O程序为10H中断处理程序。显示I/O程序的主要功能如表16-3所示。

功能

入口参数

出口参数

说明

AH=0
设置显示模式

AL=显示模式代号

可设置的显示模式与适配卡相关

AH=1
设置光标类型

CH低4位=光标开始线
CL低4位=光标结束线

文本模式下光标大小;当第4位为1时光标

不显示

AH=2
置光标位置

BH=显示页号
DH=行号
DL=列号

左上角坐标是(0,0)

AH=3
读光标位置

BH=显示页号

CH=光标开始行
CL=光标结束行
DH=行号
DL=列号

CH和CL含光标类型左上角坐标是(0,0)

AH=5
选择当前显示页

AL=新页号

AH=6
向上滚屏

AL=上滚行数
BH=填空白行的属性
CH=窗口左上角行号
CL=窗口左上角列号
DH=窗口右下角行号
DL=窗口右下角列号

1.当滚动行数为0时表示清除整个窗口
2.仅影响当前显示页

AH=7
向下滚屏

AL=下滚行数
其他参数与AH=6相同

同AH=6

AH=8
读取光标位置处的字符和属性

BH=显示页号

AH=属性
AL=字符代码

AH=9
将字符和属性写到光标位置处

BH=显示页号
AL=字符代码
BL=属性
CX=字符重复次数

光标不移动

AH=0AH
将字符写到光标位置处

BH=显示页号
AL=字符代码
CX=字符重复次数

1.光标不移动
2.不带属性

AH=0EH
TTY方式显示

BH=显示页号
AL=字符代码

光标处显示字符并后移光标;

解释回车、换行、退格和响铃等控制符

AH=0FH
取当前显示模式

AL=显示模式号
AH=最大列数
BH=当前页号

AH=13H
写字符串(在AT及其以上系统上才有此功能

AL=写模式
BH=显示页号
BL=属性
CX=字符串字符数
DH=写串起始行号
DL=写串起始列号
ES:BP=字符串首地址

1.解释回车等控制符
2.写模式仅低2位:
位0:0表示移动光标,1表示不移动光标
位1:0表示串中字符代码和属性较替,

1表示串中只含有字符代码

                                        表16-3 10H号中断处理程序的基本功能

16.2.5 举例

举例

1.调用10H号中断的5号功能,选择第0页作为当前显示页:

……

MOV AL,0

MOV AH,5

INT 10H

……

2.调用10H号中断的0FH号功能,获取当前显示页号、当前显示模式和该模式下的最大显示列数:

……

MOV AH,0FH

INT 10H

……

3.调用10H号中断的09H号功能,在当前光标位置处显示指定属性的字符,但不移动光标:

……

MOV BH,0    ;第0页

MOV BL,47H  ;红底白字

MOV CX,1    ;1个

MOV AL,'A'   ;字符为A

MOV AH,9

INT 10H

……

4.窗口滚屏时,如果滚屏行数为0,表示清除整个窗口。如果把整个屏幕作为窗口,那么就可以实现清屏。调用10H号中断的6H号功能,清除屏幕,然后把光标定到左上角:

……

MOV CH,0          ;置左上角坐标

MOV CL,0

MOV DH,24          ;置右下角坐标

MOV DL,79

MOV BH,07H       ;清除区的填充属性-黑底白字

MOV AL,0         ;清除行数为0,清整个窗口

MOV AH,6

INT 10H

MOV BH,0          ;设第0页

MOV DH,0            ;置光标定位坐标

MOV DL,0

MOV AH,2

INT 10H         ;定位光标

……

例3:屏幕中间位置窗口显示

动手实验99写一个程序,在屏幕中间部位开出一个窗口,从窗口的最底行开始接收并显示用户按键,当窗口底行显示满时,窗口内容向上滚动一行后,继续显示。

在理解下面示例程序的基础上,自己独立编写源程序。编译完成后,在debug调试器中单步跟踪调试,以验证程序的正确性。

算法分析:

第一步:选择显示页;

第二步:清屏;

第三步:定位光标左下角;

第四步:接收键盘输入,并判断是否结束;

第五步:显示字符,不带属性;

第六步:判断是否越界,如越界重置光标,上滚一行;

流程图:如图16-7所示。

        图16-7 屏幕中间位置窗口显示

示例代码74

;例3:写一个程序,在屏幕中间部位开出一个窗口,从窗口的最底行开始接收并显示用

;户按键,当窗口底行显示满时,窗口内容向上滚动一行后,继续显示

;用户按CTRL+C键时,结束运行

;程序名:t16-3.asm

;-----------------------------------------

assume cs:code

;常量定义

winwidth=40           ;窗口宽度

wintop=8                    ;窗口左上角行号

winleft=20                                    ;窗口左上角列号

winbottom=17                             ;窗口右下角行号

winright=winleft+winwidth-1  ;窗口右下角列号

color=74h                            ;属性值,白底红字

pagen=0                               ;显示页号

ctrl_c=03h                           ;结束符ASCII码

;代码段

code segment

start:

         ;选择显示页

         mov al,pagen

         mov ah,5

         int 10h

         ;清屏

         mov ch,wintop

         mov cl,winleft

         mov dh,winbottom

         mov dl,winright

         mov bh,color

         mov al,0

         mov ah,6

         int 10h

         ;定位光标左下角

         mov bh,pagen

         mov dh,winbottom

         mov dl,winleft

         mov ah,2                                                                           

         int 10h

         ;接收键盘输入

next:

         mov ah,0

         int 16h

         ;判断是否结束                                                                        

         cmp al,ctrl_c

         jz exit

         ;显示字符

         mov bh,pagen

         mov cx,1

         mov ah,0ah      ;不带颜色属性

         int 10h

         ;

         inc dl                

         ;判断是否越界

         cmp dl,winright+1

         jnz setcur                  

         ;上滚一行

         mov ch,wintop

         mov cl,winleft

         mov dh,winbottom

         mov dl,winright

         mov bh,color   

         mov al,1

         mov ah,6

         int 10h     

         ;重置光标                                                               

         mov dl,winleft

setcur:

         mov bh,pagen 

         mov ah,2

         int 10h

         jmp next                                                         

exit:

         mov ax,4c00h

         int 21h     

code ends                                                       

例4:改写示例代码69中的子程序

动手实验100在屏幕上用多种属性显示字符串“WELCOME”。

在理解下面示例程序的基础上,自己独立编写源程序。编译完成后,在debug调试器中单步跟踪调试,以验证程序的正确性。

示例代码75

;方法一:调用I/O程序中的13H号功能直接显示字符串。

;子程序名:echoa

;功能:调用I/O程序中的13H号功能直接显示字符串。

;入口参数:DS:SI=字符串首地址

;CX=字符串长度,BL=属性

;DH=显示开始行号,DL=显示开始列号

;出口参数:无

echoa proc

         push es

         push bp

         push ds

         pop es

         mov bp,si          ;满足13H功能入口参数要求es:bp为要写串首地址

         mov bh,0           ;指定显示页

         mov al,0            ;采用0号显示方式(不移动光标)

         mov ah,13h      ;字符串中不含属性,主程序BL已经有属性值

         int 10h

         pop bp

         pop es

         ret

echoa endp

该子程序与ECHO稍有不同:第13H功能解释回车和换行等控制码,所以如果要显示的字符串中含有这样的控制码,那么显示效果就会有差异,第二是当显示超出最后一行的最后一列时,13H功能就要引起滚屏。

;方法二:先调用显示I/O程序的2号功能把光标定到指定位置,然后利用显示I/O程序的TTY显示功能逐个

;显示字符串中的字符,但是由于TTY方式显示不含属性,所以先调用9号功能把指定属性写到显示字符串的

;位置处

;子程序名:echob

;---------------------------

echob proc

         jcxz echob2

         mov bh,0           ;显示页号

         mov ah,2           ;置光标位置

         int 10h

         mov al,20h       ;用指定属性写一串空格,CX长度是重复字符串个数

         mov ah,9

         int 10h

         mov ah,0eh      ;tty显示功能

echo1:

         mov al,[si]

         inc si

         int 10h               ;逐个显示字符

         loop echo1

echob2:

         ret

echob endp

除了这两个方法之外,是否还存在其他方法呢?请读者独立思考。

这篇关于【新书推荐】16.2 显示中断的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/783199

相关文章

电脑显示mfc100u.dll丢失怎么办?系统报错mfc90u.dll丢失5种修复方案

《电脑显示mfc100u.dll丢失怎么办?系统报错mfc90u.dll丢失5种修复方案》最近有不少兄弟反映,电脑突然弹出“mfc100u.dll已加载,但找不到入口点”的错误提示,导致一些程序无法正... 在计算机使用过程中,我们经常会遇到一些错误提示,其中最常见的就是“找不到指定的模块”或“缺少某个DL

Maven中引入 springboot 相关依赖的方式(最新推荐)

《Maven中引入springboot相关依赖的方式(最新推荐)》:本文主要介绍Maven中引入springboot相关依赖的方式(最新推荐),本文给大家介绍的非常详细,对大家的学习或工作具有... 目录Maven中引入 springboot 相关依赖的方式1. 不使用版本管理(不推荐)2、使用版本管理(推

mysql的基础语句和外键查询及其语句详解(推荐)

《mysql的基础语句和外键查询及其语句详解(推荐)》:本文主要介绍mysql的基础语句和外键查询及其语句详解(推荐),本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋... 目录一、mysql 基础语句1. 数据库操作 创建数据库2. 表操作 创建表3. CRUD 操作二、外键

Spring Boot + MyBatis Plus 高效开发实战从入门到进阶优化(推荐)

《SpringBoot+MyBatisPlus高效开发实战从入门到进阶优化(推荐)》本文将详细介绍SpringBoot+MyBatisPlus的完整开发流程,并深入剖析分页查询、批量操作、动... 目录Spring Boot + MyBATis Plus 高效开发实战:从入门到进阶优化1. MyBatis

查看Oracle数据库中UNDO表空间的使用情况(最新推荐)

《查看Oracle数据库中UNDO表空间的使用情况(最新推荐)》Oracle数据库中查看UNDO表空间使用情况的4种方法:DBA_TABLESPACES和DBA_DATA_FILES提供基本信息,V$... 目录1. 通过 DBjavascriptA_TABLESPACES 和 DBA_DATA_FILES

最新Spring Security实战教程之表单登录定制到处理逻辑的深度改造(最新推荐)

《最新SpringSecurity实战教程之表单登录定制到处理逻辑的深度改造(最新推荐)》本章节介绍了如何通过SpringSecurity实现从配置自定义登录页面、表单登录处理逻辑的配置,并简单模拟... 目录前言改造准备开始登录页改造自定义用户名密码登陆成功失败跳转问题自定义登出前后端分离适配方案结语前言

OpenManus本地部署实战亲测有效完全免费(最新推荐)

《OpenManus本地部署实战亲测有效完全免费(最新推荐)》文章介绍了如何在本地部署OpenManus大语言模型,包括环境搭建、LLM编程接口配置和测试步骤,本文给大家讲解的非常详细,感兴趣的朋友一... 目录1.概况2.环境搭建2.1安装miniconda或者anaconda2.2 LLM编程接口配置2

Linux虚拟机不显示IP地址的解决方法(亲测有效)

《Linux虚拟机不显示IP地址的解决方法(亲测有效)》本文主要介绍了通过VMware新装的Linux系统没有IP地址的解决方法,主要步骤包括:关闭虚拟机、打开VM虚拟网络编辑器、还原VMnet8或修... 目录前言步骤0.问题情况1.关闭虚拟机2.China编程打开VM虚拟网络编辑器3.1 方法一:点击还原VM

CSS模拟 html 的 title 属性(鼠标悬浮显示提示文字效果)

《CSS模拟html的title属性(鼠标悬浮显示提示文字效果)》:本文主要介绍了如何使用CSS模拟HTML的title属性,通过鼠标悬浮显示提示文字效果,通过设置`.tipBox`和`.tipBox.tipContent`的样式,实现了提示内容的隐藏和显示,详细内容请阅读本文,希望能对你有所帮助... 效

Redis 内存淘汰策略深度解析(最新推荐)

《Redis内存淘汰策略深度解析(最新推荐)》本文详细探讨了Redis的内存淘汰策略、实现原理、适用场景及最佳实践,介绍了八种内存淘汰策略,包括noeviction、LRU、LFU、TTL、Rand... 目录一、 内存淘汰策略概述二、内存淘汰策略详解2.1 ​noeviction(不淘汰)​2.2 ​LR