1. 程式人生 > >彙編程式設計:pc機間的通訊

彙編程式設計:pc機間的通訊

程式說明:
這是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。