570 likes | 834 Views
汇编语言. 数学科学学院计算机应用技术专业. 修兴强 & Ariel 北京师范大学数学科学学院 202.112.84.202/~xiux/download.php E-mail: xq_xiu@yahoo.com.cn. 第 15 章 BIOS 程序设计. 地址. FFFFF. ROM BIOS. F0000. 保留区. C0000. 文本和图形视频. B8000. VRAM. 图形视频. A8000. 驻留程序区 ( 应用程序可用 ). 命令行处理器的暂留部分. 命令行处理器驻留部分. 640K RAM. DOS 内核、设备驱动.
E N D
汇编语言 数学科学学院计算机应用技术专业 修兴强 & Ariel 北京师范大学数学科学学院 202.112.84.202/~xiux/download.php E-mail: xq_xiu@yahoo.com.cn
地址 FFFFF ROM BIOS F0000 保留区 C0000 文本和图形视频 B8000 VRAM 图形视频 A8000 驻留程序区 (应用程序可用) 命令行处理器的暂留部分 命令行处理器驻留部分 640K RAM DOS内核、设备驱动 软件BIOS BIOS和DOS数据 00400 中断向量表 00000 BIOS数据区 • BIOS数据区包含了ROM BIOS服务历程使用的系统数据,它位于内存的0040h段内。 汇编语言
INT 16h键盘中断 • BIOS层次仅在硬件层次之上,在该层次控制计算机有着极大的灵活性,这种方法的一个重要限制就是所有的程序必须在实地址模式或虚拟8086模式下运行。BIOS键盘处理程序INT 16h获取键盘输入。INT 16h不允许重定向,但却是读取扩展功能键、方向盘、PgUp和PgDn的最好方法,这些扩展键产生一个8位的扫描码(scan code)。对IBM兼容机而言,每个键的扫描码都是惟一的。 • 事实上,所有的按键都产生扫描码,但我们通常并不注意和ASCII字符对应的扫描码,因为这是ASCII码更加通用。当按下扩展健时,其ASCII码是00h或E0h,如下表所示: 汇编语言
键盘是如何工作的? • 键盘输入事件是从键盘控制芯片开始的,到字符被放在30字节的键盘输入缓冲区(在偏移001Eh—003Dh处)中时结束。键盘输入缓冲区在任何时刻最多可容纳15个击键,因为每次击键将产生两个字节(ASCII码+扫描码)的数据。当用户按键时将产生下列事件: • 键盘控制芯片向PC的键盘输入端口发送一个8位的扫描码(sc)。 • 输入端口引发一个中断,中断是预定义的信号,用于通知CPU一个输入输出设备需要引起注意。CPU通过执行INT 9h服务例程响应键盘中断。 • INT 9h服务例程从输入端口获取键盘的扫描码(sc)并查找对应的ASCII码(ac),如果找到了ASCII码就将ASCII码和扫描码仪器插入到键盘缓冲区中(如果扫描码没有对应的ASCII码,键盘缓冲区中的ASCII码就设为0)。 汇编语言
input port sc Keyboard sc = scan code ac = ASCII code sc sc,ac typeahead buffer INT 9h handler ac sc,ac INT 16h handler INT 21h handler 汇编语言
一旦扫描码和ASCII码被安全地放置于缓冲区中,它们就一直保存在那里,直到被当前运行的程序取出为止,有两种方法取出按键:一旦扫描码和ASCII码被安全地放置于缓冲区中,它们就一直保存在那里,直到被当前运行的程序取出为止,有两种方法取出按键: • 调用BIOS INT 16h功能从键盘缓冲区中返回扫描码和ASCII码。这在处理没有ASCII码的功能键和光标键时非常有用。 • 调用MS-DOS INT 21h功能从输入缓冲区中返回按键的ASCII码。如果按下了扩展健,必须第二次调用INT 21h以返回扫描码。 • INT 16h功能 进行键盘处理时INT 16h比INT 21h有许多明显的优点。INT 16h可在一步内同时返回扫描码和ASCII码;另外INT 16h还有一些额外的功能,如设置击键重复率和返回键盘状态标志等。击键重复率是指在按下键时击键的重复速率。当不知道用户按下的是否是扩展健时,INT 16h通常是可调用的最佳功能。 汇编语言
INT 16h功能03h(设置击键重复率) • INT 16h功能03h允许设置键盘击键重复率。当一直按着某个键时,在键开始重复之前通常有250~1000毫秒的延迟。重复速率的取值可以在1Fh(最慢)到0(最快)之间。 汇编语言
INT 16h功能05h(在键盘缓冲区中插入按键动作) • INT 16h功能05h允许你将一个按键动作送入键盘缓冲区。一个按键由两个8位整数构成:一个ASCII码和一个键盘扫描码。 汇编语言
INT 16h功能10h(等待按键) • INT 16h功能10h从键盘缓冲区中删除下一个按键。如果缓冲区中没有现成的按键存在,则键盘处理程序等待用户按键。 汇编语言
INT 16h功能11h(检查键盘缓冲区) • INT 16h功能11h允许察看键盘缓冲区内是否有按键在等待。如果有按键,则函数返回按键的ASCII码和扫描码。我们可在执行其他任务的循环内使用该功能,注意该功能并不从键盘缓冲区中删除按键。 汇编语言
INT 16h功能12h(获取键盘标志) • INT 16h功能12h返回非常有价值的关于当前键盘标志的信息。例如 字处理程序通常在CapsLock,NumLock和Insert等按下的时候在屏幕的底端显示标志或记号,这是通过不断检查键盘标志并监视其变化而做到的。 汇编语言
INT 10h视频程序设计 背景知识 • 应用程序在文本模式下向屏幕上写字符的时候,可在下列三种类型的视频输出方式中进行选择: • MS-DOS方式访问:任何运行或模拟MS-DOS的计算机都可以使用INT 21h在视频显示上写文本,输入输出可轻易地被重定向到其他设备上,如打印机和磁盘。但这种访问模式输出较慢并且不能控制文本的颜色。 • BIOS方式访问:使用INT 10h BIOS服务输出字符。执行起来比INT 21h快得多,而且允许控制文本的颜色。在填充大块屏幕区域时,通常能感觉到轻微的延迟。输出不能重定向。 • 直接视频访问:字符直接送视频RAM,因此执行是瞬时的。输出不可重定向。在MS-DOS时代,字处理程序和电子表格程序全部采用了这种方法(在Windows NT/2000/XP下这种方法仅限于全屏模式)。 • 应用程序在选择使用何种访问方式时不尽相同。那些要求高性能的程序选择直接视频访问;其他一些则选择BIOS方式访问;当屏幕输出需要重定向或要和其他程序共享屏幕时,一般使用MOS-DOS方式访问。应该说明的是,MS-DOS中断使用BIOS过程来完成它们的任务,而BIOS过程又使用直接视频访问在屏幕上输出结果。 汇编语言
在全屏幕模式下运行程序 • 使用视频BIOS绘制图形的程序应该在以下环境下执行: • 纯MS-DOS。 • Linux 下的DOS模拟器。 • MS-Windows下的全屏模式。 • 在MS-Windows下有两种方法切换到全屏模式: • 为程序的EXE文件创建一个快捷方式,打开快捷方式的属性对话框,选择屏幕标签,然后选择全屏幕模式。 • 从开始菜单中打开一个命令行窗口,然后按下Alt-Enter键切换到全屏模式。使用cd命令(改变目录)进入EXE文件所在的目录,输入程序的名字运行程序。 Alt-Enter是一个开关,再次按下它就可以返回到窗口模式。 汇编语言
理解视频文本 • 视频模式有两种类型:文本模式和图形模式。当计算机以MS-DOS引导后,视频控制器就被设置为视频模式3(彩色文本,25行80列)。 • 在文本模式下,行从屏幕最顶端(行0)开始计算,行高是当前字体的一个字符单元的高度;列从屏幕的最左边(列0)开始计算,列宽是一个字符单元的宽度。 • 字体 字符是由驻留内存的字体表生成的。最初这个表格位于ROM中,但后来版本的BIOS允许程序员在运行时重写字体表,这使得在文本模式下自定义字体成为可能。 • 视频文本页 文本模式下的视频内存被分成多个视频页,每一页都可以容纳整个屏幕的文本。应用程序可以在显示一页的时候写另外的隐藏页,并可以在页之间快速切换。在追求高性能的时代,MS-DOS程序常常要在内存中同时保留若干个文本页。随着当前图形接口的流行,文本页的特性已经不再重要了。默认的视频页是页0。 汇编语言
背景 前景(字符) A ‘A’ nn ‘B’ nn ‘C’ nn 字符 字符 字符 属性 属性 属性 • 属性 如下所示,每个字符都被赋予了一个控制字符颜色(称为前景色)和字符之后的屏幕颜色(称为背景色)的属性字节。 视频显示的每个位置容纳一个字符以及其属性(颜色)。属性以一个单独的字节存储,在内存中的位置紧跟在字符后面。在下图中,屏幕上的三个位置包含字母ABC: • 闪烁 视频显示的字符可以闪烁。视频控制器以预定的频率反转字符的前景色和背景色来做到这一点。当PC从MS-DOS模式引导时,默认情况下闪烁是被允许的,我们可以使用视频BIOS功能来关闭闪烁。在MS-Windows下打开MS-DOS模拟窗口时,默认情况下闪烁是被禁止的。 汇编语言
1 1 1 1 I R G B 色彩的控制 • 原色的混合 视频显示上的每个像素都是通过三种独立的电子束产生的:红、绿和蓝,还有一个通道用来控制像素的亮度。因此所有可用的文本颜色都可以用下表中的4位二进制值来表示(I=亮度、R=红、G=绿、B=蓝)。下图显示了一个白色像素的构成。 汇编语言
如下图所示,将三原色混合就可以产生新的色彩。进一步打开亮度位,混合后的色彩就会更亮。如下图所示,将三原色混合就可以产生新的色彩。进一步打开亮度位,混合后的色彩就会更亮。 汇编语言
如下表所示,原色和混合色彩组成了所有可能的4位色彩值。右边列表中的每种色彩都打开了亮度位。如下表所示,原色和混合色彩组成了所有可能的4位色彩值。右边列表中的每种色彩都打开了亮度位。 汇编语言
I R G B I R G B 前景 背景 闪烁 R G B I R G B 允许闪烁 前景 背景 属性字节 • 在色彩文本模式下,每个字符都被赋予了一个属性字节,该字节由两个4位的色彩代码构成,则前景色和背景色: 闪烁 这个简单的色彩方案有一点稍微复杂的地方,那就是如果当前 的显卡允许闪烁,那么背景色高位的含义就是字符是否闪烁。当该位 被设置时,字符将闪烁显示: 在允许闪烁时,上表中只有左边一栏的低亮度颜色可用做背景色(黑、 蓝、青、红、洋红、棕和浅灰)。MS-DOS引导时默认的配色方案是 二进制00000111(黑色背景、浅灰前景)。 汇编语言
构造属性字节 • 使用汇编编译器的SHL操作符将背景色值左移4位,然后与前景色进行或操作,这样就可以用两种颜色(前景和背景)构建一个属性字节。例如下面的语句创建蓝色背景浅灰色文字的属性字节: BLUE = 1 LIGHT_GRAY = 111b mov bh,(BLUE SHL 4) OR LIGHT_GRAY ;00010111 下面创建红色背景白色文字的属性值: WHITE = 1111b RED = 100b mov bh,(RED SHL 4) OR WHITE ;00010111 汇编语言
下面是在棕色背景上产生蓝色字符: BLUE = 1 BROWN = 110b mov bh,((BROWN SHL 4) OR BLUE) ;00010111 在不同的操作系统下运行程序时字体和颜色会稍微有所不同。例如,在Windows 2000下闪烁是被禁止的,除非切换到全屏模式。 汇编语言
INT 10h视频功能 • 精选的INT 10h功能 在调用INT 10h之前保护通用寄存器(使用PUSH指令)是个好主意,因为不同版本的BIOS影响寄存器的方式并不相同。 汇编语言
INT 10h功能0(设置视频模式) • INT 10h功能0允许将当前视频模式设置为文本或图形模式,一些文本模式的编号列在下表中。 汇编语言
在设置新的视频模式之前,最好首先获取(使用INT 10h功能0Fh)当前的视频模式并将其保存在变量中,在程序退出时可以利用该值恢复原始的视频模式。 汇编语言
INT 10h功能01h(设置光标起始行和结束行) • INT 10h功能01h用来设置文本光标的大小。通过定义起始扫描行和结束扫描行可以控制文本光标的现实大小。应用程序可以通过设置光标的大小以显示当前操作的状态。例如,文本编辑器可能会在NumLock键时增大光标,再次按下NumLock的时候,光标又恢复成原始大小。 汇编语言
0 1 2 3 4 5 6 顶端 7 底端 • 光标可描述为一系列的水平线,其中第0线在最顶端。默认情况下光标从第6线开始,到第7线结束,如下图所示。 汇编语言
INT 10h功能02h(设置光标位置) • INT 10h功能02h在特定视频页的特定行列位置定位光标。 汇编语言
INT 10h功能03h(获取光标位置和大小) • INT 10h功能03h返回光标的行/列位置以及决定光标大小的起始行和结束行。当用户在菜单周围移动鼠标的时候,这个功能是相当有用的。根据光标的位置,就可以知道哪个菜单项被选中了。 • 显示和隐藏光标 汇编语言
INT 10h功能06h(上卷屏幕) • INT 10h功能6上卷屏幕上矩形区域内(称为窗口)的所有文本,窗口是使用左上角和右下角的行列坐标来定义的。默认的MS-DOS屏幕从顶端开始计算有25行(0~24),从左边开始计算有80列(0~79)。因此覆盖整个屏幕的窗口从坐标(0,0)到坐标(24,79)。在下图中,CH/CL寄存器定义在左上角的行列位置,DH/DL定义右下角的行列位置。 CL CH DH DL 汇编语言
窗口上卷时,底端的行由空行代替。如果所有的行都上卷了,那么窗口就被清空了(变为空白),上卷时移出窗口的行将不能被恢复。窗口上卷时,底端的行由空行代替。如果所有的行都上卷了,那么窗口就被清空了(变为空白),上卷时移出窗口的行将不能被恢复。 • 下卷屏幕(07h) 除了窗口内文本的移动方向是向下的以外,下卷屏幕与06h的功能基本相同,它们的输入参数也是相同的。 • 例子:在窗口内显示文本(TextWin.asm)。 汇编语言
INT 10h功能08h(读取字符及其属性) • INT 10h功能08h返回当前光标位置处的字符及其属性。那些直接从屏幕读取文本的程序一般使用该功能(称为抓屏技术)。扫描屏幕上的文本,并为听力受损的用户将文本转换成语音的程序可以使用这个功能。 汇编语言
INT 10h功能09h(显示字符并设置其属性) • INT 10h功能09h在当前的光标位置显示彩色字符。正如从下表中演示的那样,这个功能可以显示任何的ASCII字符,包括ASCII码中从1--31的特殊IBM图形字符。 CX中的重复次数决定重复显示多少次字符(重复显示时字符不应当超出当前行的结尾)。在显示完字符之后,如果还要继续显示字符,必须调用INT 10h功能02h前进光标。 汇编语言
INT 10h功能0Ah(显示字符) • INT 10h功能0Ah在当前光标位置显示字符而不改变当前屏幕位置的属性。该功能除了不需指定属性值之外,其他方面与功能09h是相同的。 汇编语言
INT 10h功能10h子功能03h(切换闪烁和亮度模式) • INT 10h功能10h有许多有用的子功能,子功能03h允许将色彩属性的最高位设置为控制色彩亮度或字符的闪烁,如下表所示。 汇编语言
INT 10h功能0Fh(获取视频模式信息) • INT 10h功能0Fh返回关于当前视频模式的信息,包括模式号、显示的列数以及当前活跃视频页号。 汇编语言
INT 10h功能13h(以电传打字机方式显示字符串) • INT 10h功能13h从屏幕上指定的位置开始显示字符串。字符串可以选择包含字符及其属性值。 汇编语言
例子:显示色彩字符串 • 库过程中的例子 • Irvine16链接库中的两个过程:Gotoxy和Clrscr 汇编语言
使用INT 10h绘图 • 在画像素点之前,必须将视频适配卡设置为下表中的某种标准图形模式。 • INT 10h可以识别的视频图形模式 坐标 每种视频模式的分辨率都用XMax和YMax表示。屏幕坐标范围从左上角的x=0,y=0到右下角的x=Xmax-1,y=YMax-1。 汇编语言
和像素相关的INT 10h功能 • 写像素(0Ch) • 如下表所示,当视频控制器处于图形模式时,INT 10h功能0Ch在屏幕上绘制一个像素点。功能0Ch执行得相当慢,这在绘制大量像素时更加明显(大多数图形程序在计算完每个像素的颜色数、水平分辨率等数据后,直接向视频内存写数据)。 • INT 10h功能0Ch 汇编语言
读像素 • 如下表所示,功能0Dh读取屏幕上给定行列位置的像素值并在AL中返回。 • INT 10h功能0Dh • 画线程序 汇编语言
内存映射图形 • 前面的章节展示了如何使用INT 10h绘制像素点和线,这种方法的基本缺点是速度太慢,因为每次绘制像素点的时候不得不执行那么多的操作系统代码。本节中,我们将图形数据直接送到视频内存(VRAM)中,这种方法被称为内存映射图形技术,它更加高效。 • 模式13h:320*200,256色 • 在模式13h下直接写视频内存是最容易的,这时屏幕像素映射为一个二维字节数组,其中每个像素单独占用一个字节。数组从屏幕左上角的像素开始,屏幕顶端的一行占用320字节,下一个字节映射为第二行的第一个像素,以此类推。数组中的最后一个字节映射为屏幕右下角的像素。为什么每个像素要用一整个字节呢?这是因为需要用256个数值来表示所有可能的颜色。 汇编语言
OUT指令 像素和颜色值使用OUT指令(输出到端口)送到视频适配器,其中DX中存放16位的端口值,要发送的值存放在AL中。例如视频色彩调色板位于端口地址3C8h处,下面的指令将值20h送该端口:OUT指令 像素和颜色值使用OUT指令(输出到端口)送到视频适配器,其中DX中存放16位的端口值,要发送的值存放在AL中。例如视频色彩调色板位于端口地址3C8h处,下面的指令将值20h送该端口: mov dx,3C8h ;port address mov al,20h ;value to be output out dx,al ;send value to port • 色彩索引在模式13h中最有趣的事情是每个整数色彩值并不直接表示一种颜色,相反,该整数值表示一个被称为调色板的色彩表的索引。调色板中的每个项都由三个独立的整数(0~63)构成,称为RGB值(红、绿、蓝)。调色板的第0项控制着屏幕的背景颜色。 • 使用这种方案可以创建262 144种不同的色彩(643),但在某一时刻只能显示256钟不同的色彩,程序在运行的时候可非常容易地修改调色板以改变色彩。 汇编语言
RGB色彩RGB色彩依据的是光的叠加混合(相加色),与混合液体颜料使用的减色正好相反。例如,使用叠加混合法将所有色彩的亮度设为0就可以创建黑色。白色则正好相反,它是将所有的色彩亮度级都设为63(最大值)形成。事实上,当三种亮度相等的时候,就得到了各种灰色。RGB色彩RGB色彩依据的是光的叠加混合(相加色),与混合液体颜料使用的减色正好相反。例如,使用叠加混合法将所有色彩的亮度设为0就可以创建黑色。白色则正好相反,它是将所有的色彩亮度级都设为63(最大值)形成。事实上,当三种亮度相等的时候,就得到了各种灰色。 • 内存映射图形程序 汇编语言
鼠标程序设计 • 鼠标通常通过RS-232串口、PS-2鼠标口或无线连接同计算机的主板相连接。在探测鼠标之前,MS-DOS要求在内存中安装一个驱动程序,MS-Windows有自己内建的鼠标驱动,但现在我们将着重讲述MS-DOS提供的功能。 • 鼠标的移动是以被称为mickey的单位跟踪计量的,一个mickey代表鼠标移动大约1/200英寸。Mickey到像素的转换比率可以进行设置,默认情况下是每个水平像素对应8个mickey,每个垂直像素对应16个mickey。 • 鼠标INT 33h功能 • INT 33h提供了关于鼠标的信息,包括鼠标的当前位置、最后按下的按键和移动速度等。INT 33h还可以用来隐藏和显示鼠标光标。INT 33h在AX中而不是AH(在BIOS功能中常用)中接收功能号。 汇编语言
复位和获取鼠标状态 • INT 33h功能0将鼠标复位并确认鼠标可用。如果鼠标被发现,则该功能进行下列设置:鼠标被定位在屏幕的中心,显示页被设置为视频页0,鼠标指针被隐藏,mickey到像素的转换比率和鼠标移动速度被设置为默认值,最后,鼠标的移动范围被设置为整个屏幕。细节如下表所示: • INT 33h功能0 汇编语言
显示和隐藏鼠标指针 • 下面两张表所示的INT 33h功能1和功能2专门用于显示和隐藏鼠标指针。鼠标驱动内部保留着一个计数值,调用功能1时该计数值增1(在非0的情况下),调用功能2时该计数值减1。当计数值为0时鼠标指针被显示,功能0(复位鼠标)将该计数值设置为-1。 • INT 33h功能1 • INT 33h功能2 汇编语言
获取鼠标位置和状态 • INT 33h功能3获取鼠标的位置和状态,具体如下所示: • INT 33h功能3 汇编语言
将像素坐标转换为字符坐标MS-DOS中的字符是8像素宽、8像素高。因此像素坐标处以字符的大小就可以转换成字符坐标。假设像素位置和字符都是从0开始的,下面的公式将像素坐标p转换成字符坐标C,字符的大小用D表示:将像素坐标转换为字符坐标MS-DOS中的字符是8像素宽、8像素高。因此像素坐标处以字符的大小就可以转换成字符坐标。假设像素位置和字符都是从0开始的,下面的公式将像素坐标p转换成字符坐标C,字符的大小用D表示: C = int(P/D) • 例如,假设字符是8像素宽的,如果INT 33h功能3返回的X坐标是100(像素),那么转换为字符坐标位置就是12,因为C=int(100/8)。 • 设置鼠标位置 • INT 33h功能4将鼠标位置移到特定的X和Y坐标处,如下表所示: • INT 33h功能4 汇编语言
将字符坐标转换为像素坐标可使用下面的公式将字符坐标转换为像素坐标,其中C=字符坐标,P=像素坐标,D=字符大小:将字符坐标转换为像素坐标可使用下面的公式将字符坐标转换为像素坐标,其中C=字符坐标,P=像素坐标,D=字符大小: P = C * D • 在水平方向上,P是字符单元的左边所在位置,在垂直方向上,P是字符单元的顶端所在的位置。如果字符宽度是8个像素并且想将鼠标定位在第12个字符单元处,那么字符单元最左边的像素是96。 • 获取按钮的按下和释放 • 功能5返回鼠标按键的状态以及鼠标键最后按下的位置。在一个事件驱动的编程环境中,拖动事件总是以鼠标键的按下开始的,一旦对待定的鼠标键调用了该功能,那么该按键的状态就被重置,第二次调用该功能时什么也不会返回。 汇编语言