在C++Builder中,不能夠使用Turbo C中的outputb和inputb端口讀寫函數。但我們可以有另外兩種辦法實現這個功能。本文介紹怎樣在C++Builder下實現端口讀寫,並給出兩種方法的源代碼。
在C++Builder下對端口的讀寫共有兩種方法,一種為內嵌匯編語言,另一種為使用__emit__函數。
1 通過內嵌匯編語言實現端口的讀寫
在C++Builder中,匯編語句必須被包含在以關鍵字asm為起始的一對大括號中:
asm {
匯編語句1
……
}
利用內嵌匯編語言編制端口輸出函數如下:
void OutPort(unsigned short port,unsigned char value)//port參數為輸出端口地址,value參數為輸出值
{
asm{
mov dx , port //把端口地址送到處理器DX寄存器中
mov al , value // 把value 送到處理器AL寄存器中
out dx , al // 把AL寄存器中的值送到端口
};
}
該函數將無符號字符型8位的數據value寫入地址為port的端口上,port的數據類型是unsigned short ,16位無符號短整形。
利用內嵌匯編語言編制端口輸入函數如下:
unsigned char InPort(unsigned short port)//port參數為輸入端口地址,返回為輸入值
{
unsigned char value ;
asm{
mov dx , port // 把端口地址送到處理器DX寄存器中
in al, dx // 從DX指定端口中將一數據送到AL寄存器中
mov ind , value // 把AL寄存器中的值賦給value
};
return value; //返回端口數據
}
函數InPort從地址為port的端口讀入一個無符號8位的字符型數據,其其參數只一個,即端口號。返回的數據為unsigned char類型的,為從端口讀取的值。
2 通過__emit__函數實現端口的讀寫
__emit__ 函數一般極少用到。其用法如下:
void _ _emit_ _(argument, . . .);
該函數為C++Builder 的一個內部函數,調用的參數為機器語言指令。它在編譯的時侯,將機器語言指令直接嵌入目標碼中,不必借助於匯編語言和匯編編譯程序。
如果想使用__emit__ 函數,必須熟悉80x86處理器的機器語言指令。如果調用的參數是錯誤機器語言指令,則程序將非正常運行,並很容易導致死機。
利用__emit__函數編制端口輸出函數如下:
void OutPort(unsigned short port,unsigned char value)//port參數為輸出端口地址,value參數為輸出值
{
__emit__(0x8b,0x95,&port); // 把端口地址送到處理器EDX寄存器中
__emit__(0x8a,0x85,&value); // 把value 送到處理器AL寄存器中
__emit__(0x66,0xee); // 把AL寄存器中的值送到端口
}
利用__emit__函數編制端口輸入函數如下:
unsigned char InPort(unsigned short port)//port參數為輸入端口地址,返回為輸入值
{
unsigned char value ;
__emit__(0x8b,0x95,&port) ; // 把端口地址送到處理器DX寄存器中
__emit__(0x66,0xec); // 從DX指定端口中將一數據送到AL寄存器中
__emit__(0x88,0x85,&value); // 把AL寄存器中的值賦給value
return value; //返回端口數據
}
由這兩種方法所編制的函數注釋可以看出,它們每一句的功能都是一樣的,只是一個是嵌入了匯編語言,另一個是直接使用機器語言。
3 應用舉例
在C++Builder中,通過File/New Application菜單新建一工程。
在表單中加兩個Button控件,Caption分別為“寫端口”和“讀端口”。
將第一種方法所編制的OutPort和InPort函數拷貝到表單的頭文件中,並把這兩個函數作為表單類的在表單類的公有成員函數。
分別雙擊兩個Button控件,產生OnClick事件函數。在單元文件的.cpp文件添加如下代碼:
//---------------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
OutPort(0x378,0x00);//向地址為378H的端口輸出數據
OutPort(0x379,0x00);//向地址為379H的端口輸出數據
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button2Click(TObject *Sender)
{
int value;
value=InPort(0x37a);//從地址為37aH的端口讀入數據
}
//---------------------------------------------------------------------------
(注意,端口0x378-0x37f為打印口的I/O口,通過這種方法可以實現的打印機的控制。)
編譯運行。
將將第二種方法所編制的OutPort和InPort函數拷貝到表單的頭文件中,並把這兩個函數作為表單類的在表單類的公有成員函數,以替代掉第一種方法所編制的OutPort和InPort函數。再編譯運行,結果完全一樣。
本程序的編程環境是Win98操作系統和C++Builder5.0編程語言。