「汇编语言 第 3 版 王爽」- 参考答案:实验 17 编写包含多个功能子程序的中断例程

更新日期:2020年07月01日

参考答案

第一步、编写中断例程

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

参考文献

CSDN/汇编语言王爽第三版答案
百度文库/汇编语言实验答案 (王爽)


ToC

参考答案

第一步、编写中断例程

第二步、编写测试程序

参考文献