在int9中斷中如何使用call方式進行程序跳轉

 

 

對於一個剛讀完《王爽彙編語言》的初學者來說,在int9中斷中使用call table[0] 這種方式進行跳轉是個令人頭痛的問題。

這個問題困惱了我許多天最後還是CSDN的朋友幫我解決了這個問題!該問題出現在 《王爽彙編語言》第16章的試驗中。

 

 

 

 

 

問題如下:

這是一個16位dos程序,根據鍵盤輸入(int9中斷)來做相應的處理,以下代碼能夠正確運行,卻無法實現需要的功能!

;jmp bx               需要用註釋的這兩種方式來運行程序,任意一種均可,已在代碼中做好註釋!
;call table[0]

 

 

 

cnzdgs的回答:

我想你目前遇到的障礙是由於把代碼複製到了0:204H處而引起的。王爽發明的這種做法,如果單純編程玩玩還可以,在實際應用中是不可取的,原因很簡單,0:200H是中斷向量表範圍,不允許儲存其它數據,駐留程序應該使用相應的DOS功能調用。
對於目前遇到的問題,是因爲offset int9不等於204H,所以在int9程序中,所有用到偏移量(絕對地址)的地方都會出問題,簡單的解決辦法是在int9:前面加上org 204H,也可以用避免使用絕對地址的方式來解決,不過比較麻煩。

 

 

代碼:

 

assume cs:code
code segment
org 204h
 int9:  ;自定義的int9中斷例程
 jmp short init
 
 table_index db 2,3,4,5
 table dw sub3      ;226h,0 1,清空,2,設置前景,3,設置背景,4,屏幕向上滾動

init:
        push ax
        push bx
        push cx
        push es  
 push ds    
        in al,60h 
        pushf
        call dword ptr cs:[200h]
 mov bx,20h
 mov ds,bx
 mov bx,table[4]
 add bx,204h
 ;call sub3

;---------------------------------------------------------------------------
 ;jmp bx               需要用註釋的這兩個方式來運行程序,任意一種均可
 call table[0]
;---------------------------------------------------------------------------


 jmp int9ret
sub3:
 mov bx,0b800h
 mov es,bx
 mov bx,1
 mov cx,2000
 shl al,1
 shl al,1
 shl al,1
 shl al,1
sub3s:
 
 and byte ptr es:[bx],10001111b
 or es:[bx],al
 add bx,2
 loop sub3s
 ret
 

int9ret:
 pop ds
 pop es
        pop cx
        pop bx
        pop ax
        iret
int9end:
 nop

start:
        mov ax,cs
        mov ds,ax
        mov ax,0
        mov es,ax
        mov si,offset int9
        mov di,204h
        mov cx,offset int9end-offset int9
        cld
        rep movsb              ;安裝自定義的int9中斷例程       

         push es:[9*4]
        pop es:[200h]
        push es:[9*4+2]
        pop es:[202h]            ;保存原中斷向量
         cli
        mov word ptr es:[9*4],204h
        mov word ptr es:[9*4+2],0h    ;設置自定義的中斷向量
         sti
 mov ax,0b800h
        mov es,ax
        mov bx,0
        mov cx,2000
s:      mov byte ptr es:[bx],'A'
        add bx,2
        loop s
 
 mov cx,120
lp:     mov ah,0    ;進行120次讀取BIOS鍵盤緩衝區的操作,
         int 16h   
        loop lp   
           
        mov ax,4c00h
        int 21h

code ends
end start

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章