与前文中的例子一样,在使用象一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无法存取创建对该函数的调用所需的所有寄存器,因此不得不一次打印一个字符。不管怎样。运行该程序可以得到与前文例子相同的输出结果。