一、題目描述
編寫並安裝int 7ch中斷例程,功能爲完成loop指令功能
參數:(cx)=循環次數,(bx)=位移
測試程序如下:
assume cs:code
code segment
start: mov ax,0b800h
mov es,ax
mov di,160*12
mov bx,offset s-offset se
mov cx,80
s: mov byte ptr es:[di],'!'
add di,2
int 7ch
se: nop
mov ax,4c00h
int 21h
code ends
end start
二、安裝中斷例程
和實驗十三(1)一樣,我們需要把中斷例程代碼轉移到0:200,然後將設置7ch處的中斷向量指向0:200處即可
assume cs:code
code segment
start: mov ax,cs
mov ds,ax
mov si,offset do0
mov ax,0
mov es,ax
mov di,200h
mov cx,offset do0end-offset do0 ;中斷例程代碼地址
cld ;設置傳輸方向爲正
rep movsb ;傳輸源程序
mov ax,0
mov es,ax
mov word ptr es:[7ch*4],200h
mov word ptr es:[7ch*4+2],0 ;設置中斷向量
mov ax,4c00h
int 21h
do0: ;這裏是中斷例程的代碼
do0end: nop
code ends
end start
三、編寫中斷例程代碼
功能比較簡單,實現loop,可以將loop分解爲三個步驟:
(1)dec cx
(2)判斷cx是否爲0
(3)跳轉到指定命令
關鍵在於如何跳轉
我們知道int 7ch後棧中存儲的是CS:IP,也就是不繼續循環的話我們返回源程序要跳轉的地址,直接iret就好了,那如果繼續循環呢,在已知位移的情況下,我們只要將棧頂存儲的IP加上bx就可以使返回的地址是循環開頭的命令
需要注意的是,我們需要一個寄存器來指向棧頂,而不能直接對棧頂修改元素,默認的段地址爲ss的偏移寄存器是bp,所以我們需要把sp傳給bp,然後對[bp]進行操作
所以我們在整個過程中只改變了bp寄存器的值,我們需要還原,就要在一開始壓入棧。沒錯,這時候棧頂不再是IP了,而是bp了,所以我們實際上是要對[bp+2]進行操作
下面是中斷例程代碼
do0: push bp
mov bp,sp
dec cx
jcxz do1
add [bp+2],bx
do1: pop bp
iret
do0end: nop