编写用逻辑扇区号读写软盘的中断例程
王爽汇编语言 实验十七
一、相关资料
1、软盘
以3.5英寸软盘为例,软盘分为上下两面,每面80个磁道,每个磁道18个扇区,每个扇区512B
则软盘的大小为:2面*80磁道*18扇区*512B=1440KB(约为1.44MB)
2、BIOS对访问磁盘的支持
BIOS提供了13h号中断来访问磁盘,该中断的参数如下:
(ah)=int 13h的功能号(2表示读扇区,3表示写扇区)
(bl)=读取的扇区数
(ch)=磁道号
(cl)=扇区号
(dh)=磁头号(相当于软盘的面号)
(dl)=驱动器号(软驱从0开始,0:软盘A,1:软盘B;硬盘从80h开始,80h:硬盘c,81h:硬盘d)
es:bx 指向数据存放的缓冲区
返回值:成功:(ah)=0,(al)=读取或写入的扇区数
失败:(ah)=出错代码
二、实验要求
通过面号、磁道号、扇区号访问磁盘不太方便,可以考虑通过对软盘上所有扇区进行统一编号。编号从0开始,一直到2807,这个编号成为逻辑扇区编号。
要求安装一个新的int 7ch中断例程,实现通过逻辑扇区号对软盘进行读写操作
参数说明:
1、用ah寄存器传递功能号,0表示读,1表示写
2、用bx寄存器传递要读写的扇区的逻辑扇区号
3、用es:si指向存储读出数据或写入数据的缓冲区
三、分析
分析可得逻辑扇区号和物理扇区号对应关系如下:
逻辑扇区号 = (面号*80+磁道号)*18+扇区号-1
那么可以使用下面的算法来计算
int():描述性运算符,取商
rem():描述性运算符,取余数
逻辑扇区号 = (面号*80+磁道号)*18+扇区号-1
面号 = int(逻辑扇区号/1440)
磁道号 = int(rem(逻辑扇区号/1440)/18)
扇区号 = rem(rem(逻辑扇区号/1440)/18)+1
四、详细设计
assume cs:code
code segment
;中断例程:通过逻辑扇区号对软盘读写
;参数:ah功能号:0表示读,1表示写;dx要读写的逻辑扇区号;es:si存储读写数据的缓冲区
; al写入的扇区数,bl驱动器号
int7ch:
call count
cmp ah,0 ;ah为0,转跳到读
je read
cmp ah,1 ;ah为1,转跳到写
je write
mov ah,123 ;ah值不合法,返回
iret
read:
mov ah,2
jmp short start
write:
mov ah,3
jmp short start
start:
mov dl,bl
mov bx,si
int 13h
iret
;子程序:完成逻辑扇区的分析
;参数:dx:逻辑扇区号
;返回值:dh:面号,ch:磁道号,cl:扇区号
count:
push ax
push bx
mov ax,dx
mov dx,0
mov bx,1440
div bx
mov bh,al ;逻辑扇区号/1440的商是面号,暂存于bh中
;余数保存在dx中
mov ax,dx
mov bl,18
div bl
mov ch,al ;商是磁道号,保存在ch中
mov dh,bh ;面号传送到dh中
mov cl,ah
add cl,1 ;余数+1是扇区号,保存在cl中
pop bx
pop ax
ret
setup:
;初始化安装过程
mov ax,cs
mov ds,ax
mov si,offset int7ch
mov ax,0
mov es,ax
mov di,200h
;开始安装
mov cx,offset setup-offset int7ch
cld
rep movsb
;设置中断向量表
mov ax,0
mov es,ax
mov word ptr es:[7ch*4],0 ;ip
mov word ptr es:[7ch*4+2],20h ;cs
;安装结束,返回操作系统
mov ax,4c00h
int 21h
code ends
end setup