彙編程式設計:pc機間的通訊
阿新 • • 發佈:2019-01-02
程式說明:
這是PC機間相互通訊的例子,程式“require”為用查詢方式實現,程式“interrupt”為用中斷方式實現。
流程圖:
源程式:
require.asm
CODE SEGMENT ASSUME CS: CODE START: ;初始化波特率除數暫存器 MOV DX , 3FBH ;指向線路控制暫存器 MOV AL , 80H ;位7置1 OUT DX , AL ;傳送此位元組 MOV DX , 3F9H ;指向波特率除數的最高有效位 MOV AL , 0 ; 1200 BPS對應的最高有效位 OUT DX , AL ;傳送此位元組 DEC DX ;指向波特率除數的最低有效位 MOV AL , 60H ; 1200 BPS對應的最低有效位 OUT DX , AL ;傳送此位元組 ;初始化線路控制暫存器: MOV AL , 1BH ;資料長度為8位 , 1個奇偶校驗位 , 偶校驗 , 1個停止位 MOV DX , 3FBH ;指向線路控制暫存器 OUT DX , AL ;傳送此位元組 ;初始化中斷允許暫存器 MOV DX , 3F9H ;指向中斷允許暫存器 MOV AL , 0 ;禁止所有中斷 OUT DX , AL ;傳送位元組 READ: ;線路狀態檢測迴圈 MOV DX , 3FDH ;指向線路狀態暫存器 IN AL , DX ;取狀態位元組 TEST AL , 1EH ;檢查錯誤 JNZ ERROR ;若出錯則轉錯誤處理例程 TEST AL , 01H ;測試是否已收到資料 JNZ RECEIVE ;轉接收例程 TEST AL , 20H ;測試是否可以傳送字元 JNZ SEND ;若是轉發送例程 JMP READ ;迴圈檢測 SEND: ;傳送字元(來自鍵盤): MOV AH , 1 ;BIOS功能用以檢測是否有字元可讀 INT 16H ;BIOS鍵盤中斷 JZ READ ;若無擊鍵則返回迴圈 MOV AH , 0 ;BIOS功能用於取擊鍵碼 INT 16H ;擊鍵碼現在AL中 CMP AL , 03H ;檢測CTRL+C JZ EXIT ;若是 , 轉EXIT處結束程式 MOV DX , 3F8H ;指向傳送保持暫存器 OUT DX , AL ;傳送字元 JMP READ ;返回迴圈 RECEIVE: ;接收資料(在螢幕上顯示): MOV DX , 3F8H ;接收資料暫存器 IN AL , DX ;取新收到的字元 CMP AL , 03H ;檢測CTRL+C JZ EXIT ;若是 , 轉EXIT處結束程式 MOV DL , AL ;準備顯示字元 MOV AH , 2 ;用於顯示字元的DOS中斷 INT 21H ;顯示字元 CMP AL , 0DH ;判斷剛才收到的字元是否為回車 JNZ READ ;不是,轉線路檢測迴圈 MOV DL , 0AH ;若是,則加顯示一個換行符 MOV AH , 2 INT 21H JMP READ ;返回線路檢測迴圈 ERROR: ;出錯處理,顯示一個提示 PUSH CS POP DS MOV DX , OFFSET ERROR_MESSAGE MOV AH , 9 INT 21H EXIT: ;程式退出 MOV AH , 4CH INT 21H ERROR_MESSAGE DB 0AH , 'ERROR!$' ;定義出錯時顯示的提示 CODE ENDS END START
interrupt.asm
;程式碼段 CODE SEGMENT ASSUME CS: CODE NEW_INT: ;接收字元的中斷處理程式 STI ;CPU開中斷 ;CLI將IF置0,遮蔽掉“可遮蔽中斷”,當可遮蔽中斷到來時CPU不響應,繼續執行原指令 ;STI 與之相反,STI將IF置1,允許“可遮蔽中斷”,中斷到來轉而處理中斷 MOV DX , 3F8H ;接收字元 IN AL , DX ;從dx埠接受內容到al MOV DL , AL ;顯示接收字元 MOV AH , 2 INT 21H CMP DL , 0DH ;判斷是否為回車 JNZ L2 ;不是,轉L2處 MOV DL , 0AH ;若是,加顯示一個換行符 MOV AH , 2 INT 21H L2: MOV AL , 20H ;發中斷結束命令(EOI) OUT 20H , AL ;將al值寫入20h IRET START: ;主程式部分 MOV AH , 35H MOV AL , 0CH ;中斷號 INT 21H ;讀取原0CH號中斷服務程式的地址 PUSH BX PUSH ES ;以上地址入棧儲存(以便在程式退出時再恢復中斷矢量表中的內容) MOV AX , CS MOV DS , AX MOV DX , OFFSET NEW_INT MOV AH , 25H MOV AL , 0CH INT 21H ;修改中斷矢量表,將NET_INT位置登記為0CH號中斷服務程式的地址 ;以下初始化8250 MOV DX , 3FBH ;指向線路控制暫存器 MOV AL , 80H ;位7置1 OUT DX , AL ;傳送此位元組 MOV DX , 3F9H ;指向波特率除數的高位元組 MOV AL , 0 ; 1200 BPS對應的高位元組 OUT DX , AL ;傳送此位元組 DEC DX ;指向波特率除數的低位元組 MOV AL , 60H ; 1200 BPS對應的低位元組 OUT DX , AL ;傳送此位元組 MOV AL , 1BH ;資料長度為8位 , 1個奇偶校驗位 , 偶校驗 , 1個停止位 MOV DX , 3FBH ;指向線路控制暫存器 OUT DX , AL ;傳送此位元組 MOV DX , 3FCH ;設定MODEM控制暫存器 MOV AL , 0BH ;允許8250發中斷 OUT DX , AL MOV DX , 3F9H ;指向中斷允許暫存器 MOV AL , 1 ;允許資料接收準備好中斷 OUT DX , AL ;傳送此位元組 CLI ;關中斷,以便對中斷控制器8259A進行操作 IN AL , 21H ;讀取中斷遮蔽暫存器的內容 AND AL , 0EFH ;將COM1中斷(即IRQ4引腳)的對應位置0,允許中斷。 OUT 21H , AL ;寫入中斷控制器8259A中 STI ;開中斷 L1: ; 主程式迴圈,等待收到字元的中斷髮生。 MOV AH , 0 INT 16H ;讀取鍵盤字元 CMP AL , 03 ;比較是否為CTRL-C鍵 JNZ L1 ;若不是,繼續迴圈 EXIT: ;退出處理 MOV AH , 25H MOV AL , 0CH POP DS POP DX INT 21H ;恢復中斷矢量表中0CH號中斷服務程式的原地址。 MOV AH , 4CH INT 21H ;返回DOS CODE ENDS END START
函式功能
INTERRUPT程式通過替換DOS中斷中0CH號中斷的處理程式,實現對字元收發的響應。接收到字元後進行顯示。當程式結束後,恢復原中斷處理程式。
REQUIRE程式通過迴圈檢測埠狀態來實現對字元收發的響應。通過讀取狀態位元組,跳轉執行對應的操作。
引數傳遞
本題無引數傳遞
中斷向量計算
以REQUIRE程式為例,程式使用了10H、16H函式庫的函式呼叫。
10H號函式庫:CS=410h+2h=42h , IP=410h=40h 。中斷向量為0:40H。
16H號函式庫:CS = 416H + 2H =60H, IP =416H=58H。中斷向量為0:58H。