細心的開發者會發現,C++ Builder 不再支援 inportb()、outportb() 等傳統 I/O 連接埠操作函數。準確說,Borland C++ 僅支援 16 位應用程式的連接埠操作,32 位應用程式不再支援,而 C++ Builder 產出的是 32 位程式。這被視為設計缺失,因 PC 架構中 I/O 位址空間與記憶體位址空間向來獨立。Delphi 透過 Port 陣列實現 I/O 存取,C++ Builder 卻未提供類似機制。
__emit__)以下函數經驗證在 Windows 95 環境下可正常實現 I/O 連接埠讀寫,供參考使用。
outportb(port, value)void outportb(unsigned short int port, unsigned char value) {
// mov dx, port
__emit__(0x8B, 0x95, &port);
// mov al, value
__emit__(0x8A, 0x85, &value);
// out dx, al
__emit__(0x66, 0xEE);
}
outportw(port, value)void outportw(unsigned short int port, unsigned short int value) {
// mov dx, port
__emit__(0x8B, 0x95, &port);
// mov ax, value
__emit__(0x66, 0x8B, 0x85, &value);
// out dx, ax
__emit__(0xEF);
}
inportb(port)unsigned char inportb(unsigned short int port) {
unsigned char value;
// mov dx, port
__emit__(0x8B, 0x95, &port);
// in al, dx
__emit__(0x66, 0xEC);
// mov value, al
__emit__(0x88, 0x85, &value);
return value;
}
inportw(port)unsigned short int inportw(unsigned short int port) {
unsigned short int value;
// mov dx, port
__emit__(0x8B, 0x95, &port);
// in ax, dx
__emit__(0xED);
// mov value, ax
__emit__(0x66, 0x89, 0x85, &value);
return value;
}
__emit__ 直接發出機器碼位元組,繞過編譯器對 I/O 指令的限制。0x66 為運算元大小覆蓋前綴,使 16 位指令在 32 位程式碼段中正確執行。DX 暫存器存放連接埠號,AL/AX 存放資料,OUT/IN 指令完成實際 I/O 操作。&port, &value) 存取,屬於內嵌組語的簡易參數傳遞方式。<vcl.h> 或確保編譯器支援 __emit__。