實驗16編寫包含多個功能子程序的中斷例程

編程:安裝一個新的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 

其實兩種做法都是基於同一原理,都是重新計算偏移地址

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