# 2020-10-12 #「組合語言 第 3 版 王爽」- 參考答案:實驗 17 編寫包含多個功能子程式的中斷例程

2583542425發表於2020-10-12

參考答案

第一步、編寫中斷例程

assume cs:codeseg

codeseg segment
	;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
	;; 編寫中斷例程
	;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; 引數:ah 功能號;dx 邏輯扇區號;es:bx 存放資料的記憶體區;al 扇區數;cl 驅動器號;
int_13h:
	push bx
	push cx
	push dx

	mov si, dx 		; 暫存器不夠用,先讓出來
	
	;;;;;;; 計算 ah => 功能號
	cmp ah, 2			; 引數檢查
	ja int_13h_return
	add ah, 2			; 將我們的功能號直接對映到 int 13h 的功能號
	
	;;;;;;; 計算 al => 扇區數
	; 原題沒有要求寫入的扇區數,那麼我們假設與 int 7Ch 保持一直,即使用 al
	; 無需設定

	;;;;;;; 計算 dh => 磁頭號,面號
	push ax
	push bx
	mov ax, si
	mov dx, 0000h
	mov bx, 1140
	div bx
	mov dh, al ; 取商
	pop bx
	pop ax
	
	;;;;;;; 計算 dl => 驅動器號
	; 原題也沒有說如何指定驅動器號,因此我們假設使用 bl
	mov dl, cl
	
	;;;;;;; 計算 ch => 磁軌號
	push ax
	push dx
	mov ax, si
	mov dx, 0
	mov cx, 1440
	div cx			; 餘數用於下一步計算
	mov ax, dx
	mov cl, 18
	div cl
	mov ch, al		; 磁軌號儲存在扇中,因此傳送到 ch 中
	pop dx
	pop ax
	
	;;;;;;; 計算 cl => 扇區號 = rem( 邏輯扇區號 / 18 ) + 1
	push bx
	push ax
	mov ax, si
	mov bl, 18
	div bl			; 餘數用於下一步計算
	inc ah
	mov cl, ah
	pop ax
	pop bx
	
	;;;;;;; 計算 es:bx => 存放資料的記憶體區
	; 無需設定
	
	;;;;;;; 呼叫中斷
	int 13h
	
	;;;;;;; 返回
	int_13h_return:
	pop dx
	pop cx
	pop bx
	iret

int_13h_end:

start:
	;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
	;; 複製中斷例程
	;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
	mov ax, cs				; 開始地址
	mov ds, ax 
	mov si, offset int_13h
	mov ax, 0000h			; 目的地址
	mov es, ax
	mov di, 0200h
	mov cx, offset int_13h_end - offset int_13h
	cld
	rep movsb
	
	;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
	;; 修改中斷向量表
	;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
	mov ax, 0000h
	mov es, ax
	mov word ptr es:[4 * 7Ch + 2], 0000h
	mov word ptr es:[4 * 7Ch], 0200h
	
	mov ax, 4C00h
	int 21h
	
codeseg ends

end start

第二步、編寫測試程式

關於中斷例程測試方法:
由於我們不能直接寫入磁碟,因此驗證方法是:在 int 13h 前,檢查 面號、磁軌號、扇區號 計算是否正確。

測試讀取操作:

assume cs:codeseg
codeseg segment
start:
	; 引數:ah 功能號;dx 邏輯扇區號;es:bx 存放資料的記憶體區;al 扇區數;cl 驅動器號;
	
	; 執行如下程式,進行讀取操作
	; 在執行到 int 7Ch 的 int 13h 指令前,應有 ah=02h al=78h / ch=02h cl=03h dh=00h / dl=81h es:bx=45h:12h
	mov ah, 00h		; 功能號
	mov dx, 38		; 邏輯扇區號
	mov ax, 45h		; 存放資料的記憶體區
	mov es, ax
	mov bx, 12h
	mov al, 78h		; 扇區數
	mov cl, 81h		; 驅動器號
	int 7Ch		
	
	mov ax, 4C00h
	int 21h
codeseg ends

end start

測試寫入操作:

assume cs:codeseg
codeseg segment
start:
	; 引數:ah 功能號;dx 邏輯扇區號;es:bx 存放資料的記憶體區;al 扇區數;cl 驅動器號;
	
	; 執行如下程式,進行讀取操作
	; 在執行到 int 7Ch 的 int 13h 指令前,應有 ah=02h al=78h / ch=00h cl=02h dh=01h / dl=81h es:bx=45h:12h
	mov ah, 01h		; 功能號
	mov dx, 1441	; 邏輯扇區號
	mov ax, 45h		; 存放資料的記憶體區
	mov es, ax
	mov bx, 12h
	mov al, 78h		; 扇區數
	mov cl, 81h		; 驅動器號
	int 7Ch		
	
	mov ax, 4C00h
	int 21h
codeseg ends

end start

參考文獻

K4NZ / 參考答案:實驗 17 編寫包含多個功能子程式的中斷例程
CSDN/組合語言王爽第三版答案
百度文庫/組合語言實驗答案 (王爽)

相關文章