汇编语言随笔(16)- 对磁盘进行读写(int 13h 中断例程)和实验 17

磁盘读写

      3.5 英寸软盘分为上下两面,每面有 80 个磁道,每个磁道又分为 18 个扇区,每个扇区的大小为 512 个字节。下面的磁盘读写均以 3.5 英寸软盘为例。

      在读写扇区的时候,要给出面号、磁道号和扇区号。面号和磁道号从 0 开始,扇区号从 1 开始。
      BIOS提供的访问磁盘的中断例程为 int 13h 。读取软盘 0 面 0 道 1 扇区的内容到 0:200 的程序如下所示:

			mov ax,0
			mov es,ax
			mov bx,200h		;es:bx指向接收/读写扇区的内存区起始地址

			mov al,1		;读取/写入的扇区数目
			mov ch,0		;磁道号
			mov cl,1		;(起始)扇区号
			mov dh,0		;磁头号(对于软盘来说就是面号,因为一个面用一个磁头来读写)
			mov dl,0		;驱动器号:	软驱从 0 开始:  0,软驱 A ; 1,软驱 B。
										硬盘从 80h 开始:  80h,硬盘 C ; 81h,硬盘 D 。
			
			mov ah,2		;int 13h 的功能号(常用的:2 表示读扇区;3 表示写扇区)
			int 13h

      如果是将 0:200 中的内容写入 0 面 0 道 1 扇区的话,只需要将上面程序稍微改写一下即可:

			...			;前面的代码不变
			
			mov ah,3
			int 13h

      练习:将当前屏幕的内容保存在磁盘上。
      分析:一屏的内容占4000个字节,所以需要 8 个扇区。

		assume cs:code 
		code segment
			mov bx,0b800h
			mov es,bx
			mov bx,0

			mov al,8			;需要注意这里更改写入扇区的数目
			mov ch,0
			mov cl,1
			mov dl,0
			mov dh,0

			mov ah,3
			int 13h
		code ends
		end 

实验17

      编写包含多个功能子程序的中断例程:
      想对扇区用逻辑编号来统一表示,具体编号方法如下:
      物理扇区号            逻辑扇区号
      0 面 0 道 1 扇区            0
      0 面 0 道 2 扇区            1
      0 面 0 道 3 扇区            2
      0 面 0 道 18 扇区          17
      0 面 1 道 1 扇区            18
      0 面 1 道 2 扇区            19
      0 面 1 道 18 扇区          35
      0 面 2 道 1 扇区            35
      0 面 2 道 2 扇区            36
      0 面 2 道 1 扇区            35
      …
      0 面 79 道 18 扇区        1439
      1 面 0 道 1 扇区            1440

      可得下面的转换关系: 逻辑扇区号 = (面号 x 80 + 磁道号)x 18 + 扇区号 - 1
            由逻辑扇区号得物理扇区号的方法给出如下:
            int():取商            rem():取余数
            面号 = int(逻辑扇区号/1440)
            磁道号 = int(rem(逻辑扇区号/1440)/18)
            扇区号 = rem(rem(逻辑扇区号/1440)/18)+ 1

      任务:安装一个新的 int 7ch 中断例程,实现通过逻辑扇区号对软盘进行读写。
      参数说明:
      (1)用 ah 寄存器传递功能号:0 表示读,1 表示写;
      (2)用 dx 寄存器传递要读写的扇区的逻辑扇区号;
      (3)用 es:dx 指向存储读出数据或写入数据的内存区;

		assume cs:code
		code segment
		start: mov si,cs
			   mov ds,si
			   mov si,offset body
			   mov di,0
			   mov es,di
			   mov di,200h
			   mov cx,offset bodyend-offset body
			   cld
			   rep movsb

			   mov word ptr es:[7c*4],200h
			   mov word ptr es:[7c*4+2],0

			   mov ax,4c00h
			   int 21h

		 body: jmp short s
		 	   t db 3 dup(0)		;用来存放面号,磁道号和扇区号
		 	s: push si
		 	   push cx
		 	   push bx
		 	   push ax
		 	   
		 	   mov ax,dx
		 	   mov dx,0
		 	   mov bx,1440		;bx 中存放除数
		 	   div bx			;32位/16位
		 	   mov si,0
		 	   mov byte ptr t[si],al
		 	   mov ax,dx
		 	   mov bl,18
		 	   div bl 			;16位/8位
		 	   inc si
		 	   mov byte ptr t[si],al
		 	   inc si
		 	   inc ah
		 	   mov byte ptr t[si],ah
		 	   ;至此已将面号,磁道号和扇区号分别存入内存中
		 	   ;下面进行磁盘读写,默认读取的扇区个数为1

			   pop ax
			   pop bx
			   
		 	   mov al,1
		 	   mov si,1
		 	   mov ch,t[si]
		 	   inc si
		 	   mov cl,t[si]
		 	   mov dl,0
		 	   mov si,0
		 	   mov dh,t[si]

			   int 13h

			   pop cx
			   pop si
			   iret
			   
	  bodyend: nop

		code ends 
		end start
		 	   
		 	   
		 	    

Guess you like

Origin blog.csdn.net/Little_ant_/article/details/108714654