1. 预备知识
-
软盘,是个人计算机中最早使用的可移介质,常用的 3.5 英寸的软件容量为 1.44MB。之后由于 U 盘等可移动介质的出现,软盘的应用逐渐衰落。
-
常用的 3.5 英寸的软盘分为上下两面,每面 80 个磁道,每个磁道分为 18 个扇区,每个扇区大小为 512 B,则:
2 面 × 80 磁道 × 18 扇区 × 512 B = 1440 KB ≈ 1.44 MB
- 磁盘的访问实际由磁盘控制器进行,可以通过控制磁盘控制器来访问磁盘,且只能以扇区为单位对磁盘进行读写。在读写扇区时,要给出面号、磁道号和扇区号。面号和磁道号从 0 开始,扇区号从 1 开始:
mov ax,0
mov es,ax
mov bx,200h ;es:bx指向接受从扇区读入数据的内存区
mov al,1 ;读取的扇区数
mov ch,0 ;磁道号
mov cl,1 ;扇区号
mov dl,0 ;驱动器号,软驱从0开始、硬盘从80h开始
mov dh,0 ;磁头号,对于软盘即面号
mov ah,2 ;13h的2号功能用于读扇区;3号功能用于写扇区
int 13h
- 上述使用面号、磁道号、扇区号来访问磁盘不大方便,我们可以考虑对位于不同磁道、面上的所有扇区进行统一编号。编号从 0 开始,一直到 2879,称这个编号为逻辑扇区编号。
0面0道1扇区 0
0面0道2扇区 1
...
0面0道18扇区 17
0面1道0扇区 18
...
0面79道18扇区 1439
1面0道1扇区 1440
...
1面79道18扇区 2879
由上的内容可以看出:逻辑扇区号 = (面号 × 80 + 磁道号) × 18 + 扇区号 - 1。同理,基于逻辑扇区号得到物理编号:
面号 = int(逻辑扇区号 / 1440)
磁道号 = int(rem(逻辑扇区号 / 1440) / 18)
扇区号 = rem(rem(逻辑扇区号 / 1440) / 18) + 1
2. 实验任务 1:磁盘的写入
将当前屏幕的内容保存在磁盘上。
2.1 实验分析
一屏的内容占 4000 个字节,需要 8 个扇区,用 0 面 0 道的 1~8 个扇区存储。
assume cs:code
code segment
start:
mov ax,0b800h
mov es,ax
mov bx,0 ;es:bx指向接收从扇区读入数据的内存区
mov al,8 ;写入扇区数
mov ch,0 ;磁道号
mov cl,1 ;扇区号
mov dl,0 ;驱动器号,软驱从0开始、硬盘从80h开始
mov dh,0 ;面号
mov ah,3
int 13h ;int 13h的3号功能,写扇区
mov ax,4c00h
int 21h
code ends
end start
2.2 实验结果
无软盘,暂时无法实验。
3. 实验任务 2:逻辑扇区编号
编写子程序,实现通过逻辑扇区号对软盘进行读写。参数说明:
(1) 用 AH 寄存器传递功能号:0表示读,1表示写
(2) 用 BX 寄存器传递要读写的扇区的逻辑扇区号
(3) 用 ES:BX 指向存储读出数据或写入数据的内存区
3.1 实验分析
首先,根据预备知识的第四点,基于除法指令将逻辑磁盘号转换为面号、磁道号和扇区号:
mov ax,bx ;逻辑扇区号,被除数的低16位
mov dx,0 ;被除数的高16位
mov cx,1440
div cx ;AX存放商,DX存放余数
push ax ;保存商,即面号
mov ax,dx ;被除数的低16位
mov dx,0 ;被除数的高16位
mov cx,18
div cx ;AX存放商,DX存放余数
push ax ;保存商,即磁道号
inc dx
push dx ;保存余数并加一,即扇区号
pop ax
mov cl,al ;扇区号
pop ax
mov ch,al ;磁道号
pop ax
mov dh,al ;面号
然后,填充驱动器号、扇区数等参数:
mov dl,0 ;驱动器号,软驱从0开始、硬盘从80h开始
pop ax ;AH存放着功能号
mov al,1 ;扇区数
最后调用 disk_read 读磁盘、disk_write 写磁盘,且 ES:BX 指向操作的内存单元。整体代码为:
assume cs:code
code segment
start:
mov ax,0
mov es,ax
mov cx,200h ;es:bx指向接收从扇区读入数据的内存区
mov ah,0 ;功能号0表示读磁盘,1表示写磁盘
mov bx,1440 ;扇区逻辑号,1面0道1扇区
call disk
mov ax,4c00h
int 21h
disk:
push cx ;保存内存区的偏移地址
push ax ;保存功能号AH的内容
mov ax,bx ;逻辑扇区号,被除数的低16位
mov dx,0 ;被除数的高16位
mov cx,1440
div cx ;AX存放商,DX存放余数
push ax ;保存商,即面号
mov ax,dx ;被除数的低16位
mov dx,0 ;被除数的高16位
mov cx,18
div cx ;AX存放商,DX存放余数
push ax ;保存商,即磁道号
inc dx
push dx ;保存余数并加一,即扇区号
pop ax
mov cl,al ;扇区号
pop ax
mov ch,al ;磁道号
pop ax
mov dh,al ;面号
mov dl,0 ;驱动器号,软驱从0开始、硬盘从80h开始
pop ax ;AH存放着功能号
mov al,1 ;扇区数
pop bx ;将CX的内容存入BX中,ES:BX指向接收从扇区读入数据的内存区
cmp ah,0
je disk_read ;读磁盘
cmp ah,1
je disk_write ;写磁盘
jmp disk_ret ;其他功能号直接退出
disk_read:
mov ah,2 ;读磁盘
int 13h
disk_write:
mov ah,3 ;写磁盘
int 13h
disk_ret:
ret
code ends
end start
3.2 实验结果
无软盘,暂时无法实验。
4. 总结
-
13h 中断例程用于读写软盘,其中的 2 号功能用于读扇区、3 号功能用于写扇区
-
由于暂无软盘可供实验,后续将基于 Vmware Workstation 设置虚拟软件以供实验
-
参考:汇编语言/王爽著.——北京:清华大学出版社,2003