与前文中的例子一样,在使用象一setvideomode()这样的函数时,将频繁地调用BIOS函数。此外,就连前文例子中使用过的DOS函数(INT 21H,AH=01H和INT 21H,AH=09H)最终也要通过调用BIOS来完成它们的任务。在这种情况下,DOS只是简单地把你的DOS请求传给相应的低级BIOS函数。下面的例子很好地说明了这一事实,该例与前文中的例子完成相同的任务,只不过它完全跳过了DOS,直接调用了BIOS。
- # include <stdlib.h>
- # include <dos.h>
- char GetAKey(void) ;
- void OutputString( char * );
- main(int argc, char * * argv)
- {
- char str[128];
- union REGS regs;
- int ch;
- /* copy argument string; if none, use "Hello World" */
- strcpy(str, (argv[1] == NULL ? "Hello World" : argv[1]));
- while ((ch = GetAKey()) !=27){
- OutputString(str);
- }
- }
- char GetAKey()
- {
- union REGS regs;
- regs. h. ah = 0; /* get character */
- int86(0xl6, &xegs, ®s);
- return( (char)regs. h. al) ;
- }
- void OutputString(char * string)
- {
- union REGS regs;
- regs. h. ah = 0x0E; /* print character */
- regs. h. bh = 0;
- /* loop, printing all characters */
- for(; * string !='\0'; string+ + ){
- regs. h. al= * string;
- int86(0xl0, ®s, ®s);
- }
- }
你可以发现,唯一的变化发生在GetAKey()和OutputString()自身之中。函数GetAKey()跳过了DOS,直接调用键盘BIOS来获得字符(注意,在本例这个调用中,键入的字符并不在屏幕上显示,这一点与前文中的例子不同);函数OutputString()跳过了DOS,直接调用了Video BIOS来打印字符串。注意本例效率不高的一面——打印字符串的C代码必须位于一个循环中,每次只能打印一个字符。尽管Vidoeo BIOS支持打印字符串的函数,但C无法存取创建对该函数的调用所需的所有寄存器,因此不得不一次打印一个字符。不管怎样。运行该程序可以得到与前文例子相同的输出结果。