對於一個剛讀完《王爽彙編語言》的初學者來說,在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