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

簡明 x86 組合語言教程 (6):子程式與中斷機制全解析

     編輯:組合語言

4.1 子程式:組合語言的模組化基石

高階語言的函式擁有區域變數、參數傳遞、返回值等機制,但在組合語言中全部需自行實現。所有暫存器與記憶體預設為全域共享,若需區域變數,必須利用堆疊框架手動管理。

標準呼叫慣例

  1. 呼叫者將返回位址與參數壓入堆疊
  2. 被呼叫者以 EBP 為基址(EBP+8 起)存取參數
  3. 執行完畢以 RET/RETF 彈出返回位址跳轉

VC++ 產生的標準函式序言/結語

myTransform:
  push ebp           ; 保存呼叫者 EBP
  mov  ebp, esp      ; 建立堆疊框架
  sub  esp, 10h      ; 配置區域變數空間
  ...
  pop  ebp           ; 恢復 EBP
  ret                ; 返回

參數存取實例

; C++: int myTransform(int nInput) { return (nInput*2+3)%7; }
mov eax, dword ptr [ebp+8]  ; 取第 1 參數 nInput
lea  eax, [eax+eax+3]       ; eax = nInput*2+3 (LEA 技巧)
cdq                         ; 擴展為 64 位元被除數
mov  ecx, 7
idiv ecx                    ; edx = 餘數
mov  eax, edx               ; 返回值放入 eax

呼叫者端程式碼

push ecx             ; 參數 i
call myTransform     ; 呼叫
add  esp, 4          ; 清理堆疊 (呼叫者清理,__cdecl)
mov  dword ptr a[edx*4], eax  ; 存返回值

進階技巧:程式碼合併減少頁面錯誤

若兩函式有共同尾部程式碼(如 for(i=0;i<n;i++) sBytes[i]<<=1;),手工合併可減少程式碼體積,降低頁面錯誤機率。但代價是可讀性與維護性大幅下降,必須在演算法已最優、功能經驗證、效能獲益顯著時才考慮。

4.2 中斷:硬體事件的非同步響應

中斷向量表 (IVT)

  • 實模式位於 0000:0000,256 條目,各 4 位元組(段:位移)
  • 每條目指向一個中斷服務程式 (ISR)
  • 中斷號 = 向量索引

中斷分類

中斷處理流程

  1. 外設發出 IRQ → PIC/APIC → CPU
  2. CPU 依優先權與 IF 標誌決定是否響應
  3. 響應時:推 EFLAGS、CS、EIP 到堆疊,清 IF、TF
  4. 查 IVT/IDT 跳轉 ISR
  5. ISR 執行結束:IRET 恢復狀態繼續原程式

可重入程式碼:中斷與多執行緒的安全基石

ISR 可能被更高優先權中斷打斷並重入,因此必須編寫可重入程式碼:

  • 嚴禁使用全域/靜態變數(包括 C++ 成員變數)
  • 僅使用暫存器、堆疊區域變數、TLS (Thread Local Storage)
  • 若必須存取共享資料:CLI/STI 關閉/開啟中斷(時間極短)或使用自旋鎖

C 語言範例

// 可重入:僅用參數與區域變數
void strcpy(char* dest, const char* src) {
    while(*dest++ = *src++);
}

// 非可重入:使用全域變數
char cTemp;
void SwapChar(char* x, char* y) {
    cTemp = *x; *x = *y; *y = cTemp;  // 多執行緒/中斷下會競爭
}

// 非可重入:使用靜態區域變數
void SwapChar2(char* x, char* y) {
    static char cTemp;  // 同屬全域儲存區
    cTemp = *x; *x = *y; *y = cTemp;
}

組合語言撰寫可重入 ISR 要點

  • 避免使用標號作為變數地址(改用堆疊相對定址)
  • 盡量使用暫存器傳遞參數(如 INT 21h 用 AH 指定功能號)
  • 儘速完成,避免長時間關閉中斷影響系統即時性

實模式常用軟體中斷速查

類型來源範例
硬體中斷外部裝置訊號鍵盤、計時器、DMA 完成、網卡收封包
軟體中斷INT n 指令DOS 21h、BIOS 10h/13h/16h、系統呼叫
例外/陷阱CPU 內部事件除零錯誤、分頁錯誤、除錯中斷

小結

子程式與中斷是組合語言程式設計的核心機制。掌握堆疊框架慣例、參數傳遞規約、可重入原則,即可編寫結構清晰、安全可靠的底層程式。進階主題(保護模式 IDT、工作狀態段 TSS、中斷閘/陷阱閘/任務閘)將於高階篇深入探討。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved
中斷功能常用子功能
INT 10hBIOS 視訊服務AH=00h 設定模式、AH=0Eh 輸出字元、AH=13h 顯示字串
INT 13hBIOS 磁碟服務AH=02h 讀扇區、AH=03h 寫扇區、AH=08h 取得磁碟參數
INT 16hBIOS 鍵盤服務AH=00h 讀鍵盤、AH=01h 檢查緩衝區
INT 21hDOS 系統服務AH=4Ch 終止程式、AH=3Dh 開檔、AH=3Fh 讀檔