首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> C++ >> 關於C++

C++ Builder 實現 I/O 連接埠讀寫 (Inline Assembly)

     編輯:關於C++

問題背景

細心的開發者會發現,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 連接埠讀寫,供參考使用。

1. 寫入位元組 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);
}

2. 寫入字組 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);
}

3. 讀取位元組 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;
}

4. 讀取字組 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) 存取,屬於內嵌組語的簡易參數傳遞方式。

注意事項

  • 僅在 Windows 9x/Me (VxD 架構) 下保證有效;Windows NT/2000/XP 以降核心模式驅動程式才能直接存取 I/O 連接埠,使用者模式程式會觸發權限違例。
  • 需包含 <vcl.h> 或確保編譯器支援 __emit__。
  • 直接操作硬體連接埠風險極高,錯誤操作可能導致系統死機或硬體損壞,請極度謹慎使用。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved