編程:安裝一個新的int7ch中斷例程,爲顯示輸出提供以下功能子程序
(1)清屏;
(2)設置前景色
(3)設置背景色
(4)向上滾動一行
入口參數說明如下:
(1)用ah寄存器傳遞功能號:0表示清屏,1表示設置前景色,2表示設置背景色,3表示向上滾動一行
(2)對於1,2號功能,用al傳遞顏色值, al∈{0,1,2,3,4,5,6,7}。
完整代碼如下:
assume cs:code
stack segment
db 128 dup (0)
stack ends
code segment
start:push cs
pop ds ;這裏賦值只是用來複制代碼塊
mov si, offset int7c
mov ax, 0
mov es, ax
mov di, 204h
mov cx, offset int7cend - offset int7c
cld
rep movsb
;保存原有int 9號中斷處理程序的入口地址
push es:[7ch*4]
pop es:[200h]
push es:[7ch*4+2]
pop es:[202h]
;設置中斷向量表
cli
mov word ptr es:[7ch*4], 204h
mov word ptr es:[7ch*4+2], 0
sti
;調用
mov al, 1
mov ah, 0
int 7ch
mov ax, 4c00h
int 21h
;-----------新的int 7c中斷例程-------------
int7c: jmp short set
table dw cls, frontColor, backColor, scroll
set: push bx
cmp ah, 3
ja int7cret
mov bl, ah
mov bh, 0
add bx, bx
call word ptr table[bx]
int7cret: pop bx
iret
;-----------清屏----------------
cls: push bx
push cx
push es
mov bx, 0b800h
mov es, bx
mov di, 0
mov cx, 2000
s1: mov byte ptr es:[di], ' '
add di, 2
loop s1
pop es
pop cx
pop bx
ret
;-----------設置前景色----------------
frontColor:
push bx
push cx
push es
mov bx, 0b800h
mov es, bx
mov bx, 1
mov cx, 2000
s2: and byte ptr es:[bx], 11111000B
or es:[bx], al
add bx, 2
loop s2
pop es
pop cx
pop bx
ret
;-----------設置背景色----------------
backColor:
push bx
push cx
push es
mov cl, 4
shl al, cl
mov bx, 0b800h
mov es, bx
mov bx, 1
mov cx, 2000
s3: and byte ptr es:[bx], 10001111B
or es:[bx], al
add bx, 2
loop s3
pop es
pop cx
pop bx
ret
;-----------滾動一行----------------
scroll: push cx
push es
push ds
push si
push di
mov si, 0b800h
mov es, si
mov di, 0h
mov ds, si
mov si, 160
mov cx, 24
cld
s4: push cx
mov cx, 160
s5: rep movsb
pop cx
loop s4
mov cx, 80
mov di, 0
s6: mov byte ptr es:[160*24 + di], ' '
add di, 2
loop s6
pop di
pop si
pop ds
pop es
pop cx
ret
int7cend:nop
code ends
end start
程序編譯運行後發現未按照預期執行,查看標號中的地址如圖
原來,程序在編譯的時候編譯器已經計算好了標號的地址爲圖中所示:005F,007A,0098,00BA,新的中斷例程在裝載的時候重置了cs和ip的值,但是標號的偏移地址發生了改變,因此指向了錯誤的位置。我們可以利用僞指令org來通知編譯器重新計算標號的地址,改動如下:
重置一下標號的地址
可以看到,此時標號處的地址正確顯示了,還有一種改法如下:
table dw cls - int7c + 204H,frontColor - int7c + 204H,backColor - int7c + 204H,scroll - int7c + 204H
其實兩種做法都是基於同一原理,都是重新計算偏移地址