最近闲来无聊,在 上海图书馆 借了本《IBM-PC汇编语言程序设计》。没想,在看显示器访问的那章时。觉得作者讲得实在含糊,无法让人明白。后来,又借了本《80x86汇编语言程序设计》发现,这两本书在那一章节的内容几乎是一样,例子图片都一样。在我反复的摸索和在 上海科学技术情报研究所 里查看几天的资料后。终于模清了门路。当然,我也上网看了。没有相关的内容,也许是我没找到。所以,在这里献上我的成果希望有缘人能和我交流。
本文主要是介绍不用BIOS中断在VGA 640*480 16色模式下,对屏幕单个象素进行读写操作。我将用两段代码来说明如何操作,用于对各位处于迷茫的学者们一些提示。
在阅读本文前,我希望读者能够有一定的汇编基础,和对VGA显卡原理的基础知识(其实只要知道一些就可以了)。如果有空,可以在看本文之前阅读前面我借的两本书中的一本中,有关VGA显示卡的操作内容。
本文使用的例子,是用于NASM汇编器,读者可以从网上免费下载。我使用的软件,都可以从www.sf.net免费下载。
对VGA的读操作
首先,我们还是要计算点在内存中的位置。由于我们在上一章已经介绍过了。所以,这里我们就不多做解释了。直接写出代码。
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;开始计算x/8 ;开始计算y*80 ;开始汇总计算 mov bl,al add dx,bx ;dx+bx mov word[x],dx ;恢复数据 x: dw 0 |
上面的代码其实就是抄袭了(1)的代码,这里再写一遍是为了没有读(1)的读者考虑。
然后,我们还是要在八个二进制中,找到我们要的指定象素。不同的是这次我们要选择一个比较有效的方式。而且,我们要保护y内的偏移量,便于我们以后再次使用。有关16色的工作原理,我想我们就不要再温习了。所以,我们就直接切入正题。
现在,假设你已经知道锁存,位面的关系。那么,我们要考虑如何将一些支离破碎的颜色组合起来。下面我们先来确定读取象素的位置。所以,我们给出了(1)中相同的代码。不同的是,我们在后面的使用方式不同。
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; mov cx,word[y] ;将偏移量入cx ;恢复现场 b: db 0 ;程序运行完成,b中的内容为写入的数据位置。 |
记得,上面的y和b内的内容。我后面要使用他们来做一个相对效率较高的运算。如果,各位有更好更快更稳定的方式,记得一定要告诉我!记得!
最后,我就要读出内存中的颜色信息了。大家知道,颜色的四位是分别在四个锁存内的。所以,我们要对同一地址读四次才能获得。而每次读出会有一个字,也就是八个象素的四分之一。我们将用test 也就是 and (逻辑乘,也叫与)来获得。然后,用or(逻辑加,也叫或)来读入临时的寄存器。下面我们废话少说,来动手做吧。我们会用读模式0来完成读操作。
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;我们要设置模式寄存器内为读模式0 mov dx,3cfh ;我们要在读数据前,设置初始化操作 mov dx,3ceh ;下面我们要开始读数据了 mov al,byte[es:bx] ;读取数据 mov al,byte[es:bx] ;读取数据 mov al,byte[es:bx] ;读取数据 mov al,byte[es:bx] ;读取数据 ;最后,我们要整理数据了,好让它输出成我们要的数据 mov cx,word[y] mov al,ah ;将数据保存入al,便于数据返回。 pop es ;到这里,程序算是完成了 |
下面,我照例把完成的子程序代码贴出来。其实,就是上面三组代码的整合。(听起来像IBM说的“整合”)。不过这里注释就不加了,因为上面都有了。
下面这段代码在Nasm下编译成功,并且运行良好。
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; mov ax,cx pop ax mov ax,word[x] mov word[x],dx mov al,ah ;S1 End ;S2 Start mov cx,word[y] pop cx ;S2 End ;S3 Start push bx mov dx,3ceh mov dx,3cfh mov bx,word[x] mov dx,3ceh mov dx,3cfh mov al,byte[es:bx] mov dx,3cfh mov al,byte[es:bx] mov dx,3cfh mov al,byte[es:bx] mov dx,3cfh mov al,byte[es:bx] mov cx,word[y] mov al,ah pop es ;S3 End ret |
我这次使用的工具,想和大家分享一下。我使用的是Emacs编译,NASM编译。不错的。可以在Win32和Linux下用。感觉非常不错。如果各位有兴趣,也可以用用看。虽然,Emacs上手比较难,但是,知道一些基本操作后,你会发现它有多么迷
STUDIO软件开发组(SDT)
STUDIO Development Team
北斗星君(黄庠魁)
2005年1月