摘要:本文介紹了利用Turbo C編譯系統(tǒng)中提供的系統(tǒng)標(biāo)準(zhǔn)函數(shù)int86()和intdos()采用中斷方式對(duì)BIOS和DOS實(shí)現(xiàn)調(diào)用,以便充分利用系統(tǒng)的硬件資源,提高程序的運(yùn)行效率。
關(guān)鍵詞:Turbo C;BIOS;DOS;調(diào)用
一、引言
在以intel 80X86芯片為CPU的微型計(jì)算機(jī)中,對(duì)鍵盤(pán)、顯示器、磁盤(pán)驅(qū)動(dòng)器等低級(jí)操作是由固化在只讀存儲(chǔ)器ROM中的BIOS程序來(lái)完成,而MS-DOS是使用在微型機(jī)上的一個(gè)磁盤(pán)操作系統(tǒng)。它提供了高一層的與機(jī)器硬件打交道的接口,同時(shí)還具有文件管理、存儲(chǔ)管理等功能。因此,充分利用ROM-BIOS和DOS中的函數(shù)[1],不僅可以有效地利用系統(tǒng)資源,而且能夠大大提高程序的開(kāi)發(fā)效率和質(zhì)量,以及完成復(fù)雜的程序功能。
Turbo C編譯系統(tǒng)[2]中提供的系統(tǒng)標(biāo)準(zhǔn)函數(shù)int86()和intdos()采用中斷方式對(duì)BIOS和DOS實(shí)現(xiàn)調(diào)用。充分利用系統(tǒng)的硬件資源,提高程序的運(yùn)行效率。
二、調(diào)用BIOS功能
在Turbo C中提供int86()函數(shù)來(lái)調(diào)用BIOS系統(tǒng)函數(shù)的,int86()函數(shù)的原型說(shuō)明為:
int int86(int intnumber, union REGS *in_regs, union REGS out_regs);
參數(shù)說(shuō)明:
1.intnumber是中斷調(diào)用號(hào),下面列出BIOS系統(tǒng)調(diào)用的中斷調(diào)用號(hào)及其所調(diào)用的功能如表1所示。
在進(jìn)行BIOS調(diào)用時(shí),必須指出中斷調(diào)用號(hào)。
2.in_regs是一個(gè)聯(lián)合型REGS變量,聯(lián)合REGS在dos.h中定義如下:
struct WORDREGS
{
unsigned int ax,bx,cx,dx,si,di,cflag;
};
struct BYTEREGS
{
unsigned char al,ah,bl,bh,cl,ch,dl,dh;
};
union REGS
{struct WORDREGS x;
struct BYTEREGS h;
};
(表1)
in_rges用來(lái)存放指定中斷調(diào)用所需要的參數(shù)信息。這些參數(shù)被放在AL、BX、CX和DX寄存器中,并通過(guò)AH寄存器中的值來(lái)確定調(diào)用的功能。例如,中斷10H完成的是對(duì)顯示器I/O操作。根據(jù)存放在AH寄存器中的值可以進(jìn)一步確定完成的是哪一種顯示器I/O操作功能。顯示器I/O操作有17種功能[3],如表2所示。
其中的每一個(gè)功能調(diào)用,還需要在指定的寄存器中放入相應(yīng)的參數(shù)。
如功能調(diào)用02H,需要在DH和DL寄存器中存放光標(biāo)定位的坐標(biāo)值,DH中存放行坐標(biāo),DL中存放列坐標(biāo)。BH寄存器中存放光標(biāo)的顯示頁(yè)數(shù)。
3.out_regs也是聯(lián)合型REGS變量,用來(lái)存放中斷調(diào)用返回后當(dāng)前寄存器的值。
int86()函數(shù)在中斷完成后返回AX寄存器的值。若位標(biāo)志被置位,即(out_regs->x.cflag!=0),則表示出錯(cuò)。
實(shí)例:利用BIOS中斷10H和功能調(diào)用06H來(lái)完成清屏幕的操作。
#include
#include
#include
main()
{char attr=7;
int row,col;
for(row=0;row<24;row++)
{for(col=0;col<79;col++)
putchar('\');}
getch();}
clear_screen(char attr)
{unionREGS regs;
regs.h.ah=6;
regs.h.al=0;
regs.h.ch=0;
regs.h.cl=0;
regs.h.dh=24;
regs.h.dl=79;
regs.h.bh=attr;
int86(0x10,regs,regs);}
說(shuō)明:函數(shù)clear_screen()為清屏函數(shù)。寄存器CH、CL和DH、DL中分別存放的是整個(gè)屏幕的左上角坐標(biāo)和右下角坐標(biāo)。AH寄存器中存放的是功能調(diào)用號(hào)06H,若將06H功能用于清屏,則AL寄存器中必須存放零,否則AL中存放滾動(dòng)的文本行數(shù)。BH寄存器中存放的是清除屏幕的屬性,當(dāng)bh=7時(shí),屏幕清除后為黑色。
三、調(diào)用DOS功能
DOS功能調(diào)用是通過(guò)系統(tǒng)中斷調(diào)用21H來(lái)完成的。在Turbo C系統(tǒng)中提供了intdos()函數(shù)來(lái)完成DOS功能調(diào)用。MS-DOS中系統(tǒng)中斷21H的功能號(hào)從00H到62H,包含了約上百種不同的功能。表3列出了其中的部分功能。
Turbo C中使用intdos()函數(shù)來(lái)完成DOS功能調(diào)用。intdos()函數(shù)的原型說(shuō)明為:
int intdos(union REGS *in_regs,union REGS *out_regs);
intdos()的函數(shù)的調(diào)用方法與int86()函數(shù)基本相同,只不過(guò)是不用填入中斷號(hào)。intdos()函數(shù)就是調(diào)用中斷21H。同樣intdos()函數(shù)被調(diào)用時(shí)必須將功能調(diào)用號(hào)放入AH寄存器中,若所調(diào)用的功能還需要其它參數(shù),則將這些參數(shù)放入所要求的寄存器中。
實(shí)例:使用DOS功能調(diào)用2AH按月-日-年的形式返回日期。CX寄存器中存放年份,DH寄存器中存放月份,DL寄存器中存放日期。
#include
#include
#include
char *read_date();
main()
{char *pdate;
pdate=read_date();
printf(\"%s\\",pdate);}
char *read_date()
{char *month[12]={\"Anuary\",\"February\",\"March\",\"April\",\"May\",\"June\",\"July\",
\"August\",\"September\",\"October\",\"November\",\"December\"};
char date[20];
union REGS regs;
regs.h.ah=0x2A;
intdos(regs,regs);
sprintf(date,\"%s %d %d\\",month[regs.h.dh-1],regs.h.dl,regs.x.cx);
return(date);}
說(shuō)明:在read_date()函數(shù)中使用sprintf()函數(shù)將所讀取的日期按月日年的格式合并為一個(gè)字符串存入字符串date[]中。
(表3)
四、結(jié)束語(yǔ)
通過(guò)上面的實(shí)例,讀者對(duì)如何在Turbo C下使用int86()函數(shù)來(lái)調(diào)用BIOS系統(tǒng)功能有一個(gè)大概的了解,雖然BIOS功能調(diào)用能簡(jiǎn)練程序代碼,提高程序運(yùn)行效率和功能。但有一點(diǎn)也必須注意,即BIOS是一組低級(jí)軟件程序,它駐留在系統(tǒng)板上的只讀存儲(chǔ)器(ROM)中。BIOS程序本身直接與外部設(shè)備進(jìn)行通訊,并為編程人員提供了一個(gè)簡(jiǎn)單的接口。在計(jì)算機(jī)硬件不同的情況下,為了保持軟件的兼容性,而必須對(duì)BIOS程序做相應(yīng)的改動(dòng)。因此,一個(gè)有調(diào)用BIOS語(yǔ)句的程序在兼容機(jī)上有可能不能運(yùn)行,這就是說(shuō)對(duì)移植性要求較高的程序,盡可能不要使用BIOS程序調(diào)用。
參考文獻(xiàn)
[1] 顏暉.C語(yǔ)言程序設(shè)計(jì)實(shí)驗(yàn)指導(dǎo)[M],北京:高等教育出版社,2008.
[2] 張引. C程序設(shè)計(jì)基礎(chǔ)課程設(shè)計(jì)[M],杭州:浙江大學(xué)出版社,2007.
[3] 譚浩強(qiáng). C程序設(shè)計(jì)[M],北京:清華大學(xué)出版社,2004.