匯編語言:實驗十三 編寫、應用中斷例程


第Ⅰ部分

1.編寫並安裝int 7ch中斷例程,功能為顯示一個用0結束的字符串,中斷例程安裝在 0:200處。
參數:(dh)= 行號,(dl)= 列號,(cl)= 顏色,ds:si指向字符串首地址。

Solution

第一部分實驗與匯編語言:實驗十二 編寫0號中斷的處理程序類似,這里就貼上代碼吧:

assume cs:code, ds:data

code segment
start:
	jmp install
	mov dh, 10
	mov dl, 10
	mov cl, 2
	mov ax, data
	mov ds, ax
	mov si, 0
	int 7ch
	mov ax, 4c00h
	int 21h
	
install:
	mov ax, 0
	mov es, ax
	mov word ptr es:[4 * 7ch], 200h
	mov word ptr es:[4 * 7ch + 2], 0;安裝中斷向量表
	
	mov ax, cs
	mov ds, ax
	mov ax, 0
	mov es, ax
	mov si, 0
	mov di, 200h
	mov cx, offset do7chEnd - offset do7ch
	cld
	rep movsb
	
do7ch:
data segment
	db "welcome to masm!", 0
data ends

	push cx
	push si
	push di
	
	mov ax, 0b800h
	mov es, ax
	mov ax, data
	mov ds, ax
	mov si, 0;源地址偏移
	mov al, dh
	mov bl, 160
	mul bl	;dh * 160
	add ax, dl
	mov di, ax

trans:
	mov cl, [si]
	mov ch, 0
	jcxz fin;如果cx = 0,表示已經處理完畢
	mov byte ptr es:[di], cl
	mov byte ptr es:[di + 1], 11000010B
	inc si
	add di, 2
	jmp trans

fin:
	pop di
	pop si
	pop cx
	iret
	
do7chEnd:
	nop
code ends
end start

需要注意的還是在 data segment 的放置,如果直接放在主程序中會出現意想不到的錯誤哦,必須將其放在子程序中。

運行效果:
在這里插入圖片描述

第Ⅱ部分

編寫並安裝 int 7ch 中斷例程,功能為完成 loop 指令的功能。
參數:(cx)= 循環次數,(bx)= 位移。
在這里插入圖片描述

Solution

程序總體涉及到多個部分,不過大體上跟之前一樣,只是在中斷處理程序上有不一樣的處理方式。

install子程序

先看中斷子程序是如何被安裝到指定位置的(為了方便觀看,這里放上了Notepad++中的代碼截圖):
在這里插入圖片描述

這段代碼也不難,首先是保存相關寄存器,然后填寫中斷向量表,緊接着將中斷處理程序的代碼拷貝到指定地址,最后從棧中恢復寄存器的值。

do7ch中斷處理程序

在這里插入圖片描述
首先是保存bp寄存器(保護工作),int 7ch實現loop指令的功能,在循環的時候需要做如下操作:

  1. dec cx;循環計數變量減一
  2. 如果cx為0,那么不再循環,執行循環代碼后面的程序
  3. 如果cx不為0,那么繼續循環,CS:IP指向循環體開始部分。
    如何讓程序跑回循環開始的位置呢?這里bx寄存器已經保存了循環體代碼的長度,中斷處理過程如下:
    在這里插入圖片描述
    所以,棧中是保存了調用程序的位置(IP),那么怎么訪問到IP呢,很簡單,[sp + 2]即可,最上層為bp(我們自己壓入的),然后就是IP,再下面是CS,因為bp的長度為2,所以往后偏移2字節即可獲得IP的值。(棧的內容如下圖)
    在這里插入圖片描述
    完整程序:
assume cs:code

code segment
start:
	call install	;調用中斷安裝程序
	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
	
	
install:
	push ax
	push es
	push ds
	push si
	push di
	push cx
	
	mov ax, 0
	mov es, ax
	mov word ptr es:[4 * 7ch], 200h
	mov word ptr es:[4 * 7ch + 2], 0;填寫中斷向量表
	
	;將中斷處理程序拷貝到指定地址
	mov ax, cs
	mov ds, ax
	mov ax, 0
	mov es, ax	;目的段地址 0
	mov si, offset do7ch;源偏移地址
	mov di, 200h;目的偏移地址
	mov cx, offset do7chEnd - offset do7ch;程序的長度
	cld
	rep movsb
	
	pop cx
	pop di
	pop si
	pop ds
	pop es
	pop ax
	ret
	
do7ch:;從棧中取出子程序的偏移地址
	push bp
	mov bp, sp
	dec cx
	jcxz fin	;如果cx已經為0了,那么不再進行跳轉,順序執行即可
	add [bp + 2], bx;修改IP指向使其指向s程序開始處
fin:
	pop bp
	iret
do7chEnd:
	nop
code ends
end start

運行結果

在這里插入圖片描述
還差最后一道題,明天更新~

-------------------------------我是分割線 9.22更-----------------------------------

第Ⅲ部分

下面的程序,分別在屏幕的第2、4、6、8行顯示4句英文詩,補全程序。
在這里插入圖片描述
在這里插入圖片描述

Solution

需要補充的地方並不多,首先要知道,這道題是為了讓我們熟悉使用BIOS和DOS提供的中斷例程編程。

int 10h中斷例程是 BIOS 提供的中斷例程。其中包含了多個和屏幕輸出相關的子程序。這里使用int 10h中斷例程的設置光標的功能來完成在屏幕上的定向輸出。

mov ah, 2	;置光標
mov bh, 0	;0頁
mov dh, 5	;dh中放行號
mov dl, 12	;dl中放列號
int 10h

(ah)= 2表示調用第 10h 號中斷例程的2號子程序,功能為設置光標位置,可以提供光標所在的行號和頁號作為參數。

第一處需要填的就是調用int 10h 中斷例程需要指定的那些個參數:
在這里插入圖片描述


int 21h中斷例程是 DOS 提供的中斷例程,其中包含了 DOS 提供給程序員在編程時調用的子程序。

在書中的13.7章節中使用了int 21h中斷例程在光標位置顯示字符串的功能:

ds:dx 指向字符串	;要顯示的字符串需用"$"作為結束符
mov ah, 9	;功能號9,表示在光標位置顯示字符串
int 21h

(ah)= 9 表示調用第21h號中斷例程的9號子程序,功能為在光標位置顯示字符串,可以提供要顯示字符串的地址作為參數。

第二處同樣是為調用中斷例程而設定參數:(設置需要輸出的字符串位置)
在這里插入圖片描述

最后兩個需要填寫的位置:修改偏移地址,為下一次循環做准備。
在這里插入圖片描述
完整程序

assume cs:code
code segment
s1: db 'Good,better,best,', '$'
s2: db 'Never let it rest,', '$'
s3:	db 'Till good is better,', '$'
s4: db 'And better,best.', '$'
s: 	dw offset s1, offset s2, offset s3, offset s4
row:db	2,4,6,8

start:
	mov ax, cs
	mov ds, ax
	mov bx, offset s
	mov si, offset row
	mov cx, 4
ok:
	mov bh, 0	;0頁
	mov dh, ds:[si]	;行號
	mov dl, 0	;列號
	mov ah, 2	;置光標
	int 10h
	
	mov dx, ds:[bx]
	mov ah, 9
	int 21h
	inc si	;更改顯示位置
	add bx, 2	;改變偏移地址 2byte
	loop ok
	
	mov ax, 4c00h
	int 21h
code ends
end start

運行效果

在這里插入圖片描述


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM