本文介绍怎样在C ++Builder
下实现端口读写,并举出一个具体例子。
_emit_ 函数介绍
_emit_ 函数一般极少用到,通过使用C ++Builder 的Help
菜单,可得到该函数的联机帮助信息。
_emit_ 函数用法为:
void _emit_(argument,...);
该函数为C ++Builder
一个内部函数,调用的参数为机器语言指令。它在编译的时侯,将机器语言指令直接嵌入目标码中,不必借助于汇编语言和汇编编译程序。在Borland
C ++中,它的原型在头文件中说明, 而C ++Builder
的编译器能自动认识它, 不必加入头文件。
该函数无返回值。
下面利用该函数定义一个inportb 和outportb 函数,使之具有Borland C
++中inportb 和outportb 函数的功能。
void outportb(unsigned short int port, unsigned char value)
//port 参数为输出端口地址,
value 参数为输出值
{
_emit_(0x8b, 0x95, &port);
// 把端口地址送到处理器
32 位EDX 寄存器中
_emit_(0x8a, 0x85, &value);
// 把value 送到处理器8 位AL 寄存器中
_emit_(0x66, 0xee);
// 把AL 寄存器中的值送到端口
}
这个outportb 函数调用后,把value 参数指定的值送到port
参数指定的端口。
unsigned char inportb(unsigned short int port)
//port 参数为输入端口地址
{
unsigned char value;
// 指定变量value 为无符号字符型
_emit_(0x8b, 0x95, &port);
// 把端口地址送到处理器
32 位EDX 寄存器中
_emit_(0x66, 0xec);
// 从指定端口中将一数据
字节送到8 位AL 寄存器中
_emit_(0x88, 0x85, &value);
// 把AL 寄存器中的值赋给value
return value;// 返回函数值
}
这个inportb 函数调用后,从port
参数指定的端口读入并返回一个字节。
如果用户想使用_emit_ 函数,必须熟悉80x86
处理器族的机器语言指令。如果调用的参数是错误机器语言指令,则程序将非正常运行,并很容易导致死机。
应用举例
本程序的编程环境是Win98 操作系统和C ++Builder 4.0 编程语言。
启动C ++Builder4.0, 激活菜单File/New Application,
创建一个工程。在表单上添加两个Button
控件。各对象属性设置如下:
构件名称 属性 属性值
表单构件 Name Form1
Caption 读写端口
命令按钮 Name Button1
Caption
写端口
命令按钮 Name Button2
Caption
读端口
在单元文件的.h 文件添加如下代码:
public:
// 声明inportb 和outportb
函数为公有成员函数
void _fastcall outportb
(unsigned short int port, unsigned char value) {
_emit_(0x8b,0x95, &port);
_emit_(0x8a,0x85, &value);
_emit_(0x66, 0xee);
}
// ------------
unsigned char inportb(unsigned short int port)
{
unsigned char value;
_emit_(0x8b, 0x95, &port);
_emit_(0x66, 0xec);
_emit_(0x88, 0x85, &value);
return value;
}
也可将inportb 和outportb 函数的实现放在单元文件的.cpp 文件中。C
++Builder 支持成员函数的实现放在类体内或类体外的C ++标准。
分别双击两个Button 控件,产生OnClick 事件函数。在单元文件的.cpp
文件添加如下代码:
void _fastcall TForm1::Button1Click
(TObject *Sender) {
outportb(0x2c0,0x00);
// 向地址为2c0H 的端口输出数据
outportb(0x2c1,0x00);
// 向地址为2c1H 的端口输出数据
}
// -------------
void _fastcall TForm1::Button2Click
(TObject *Sender)
{
int i;
i=inportb(0x2c2);
// 从地址为2c2H 的端口读入数据
}
上面是一个对I/O 端口进行读写操作的简单例子,只要将定义inportb
和outportb
函数的代码如上所述包含到单元文件中,通过调用可方便地实现I/O
端口读写。