现在的位置: 首页 > 综合 > 正文

利用BIOS指令实现读磁盘

2013年05月27日 ⁄ 综合 ⁄ 共 4543字 ⁄ 字号 评论关闭

利用BIOS指令实现了读磁盘

 

在大多数情况下,程序只指定读一个扇区或读取一个磁道上的全部扇区。读操作只是顺序读取CH和CL指定的扇区内容,并递增CH和CL中的磁道号和扇区号,如果扇区号超过了磁道的最大扇区号,必须把扇区号重新置1,并把磁道号增1,或者把双面盘的0面变1面。

(1)本程序计算每一个磁盘地址,每次读操作之后,扇区号+1,当扇区号加到10则重新置扇区号为1,如果盘面是1则增加磁道号,然后改变盘面,或由0改为1或由1改为0
(2)数据项CurrentAddr包含起始的磁道/扇面地址,EndAddr包含结束的磁道/扇面地址。

 

BIOS磁盘操作INT 13H处理的记录都是一个扇区(512 bytes)的大小,都是以实际的磁道号和扇区号寻址的。读,写和检验磁盘文件之前,先把下列寄存器初始化:

AH = 要执行的操作:复位(0), 读状态(1), 读磁盘(2), 写磁盘(3), 检验扇区(4)
AL = 扇区数
CH = 柱面/磁道号(0为起始号)
CL = 起始扇区号(1为起始号)
DH = 磁头/盘面号,对软盘是0或1
DL = 驱动器号: 软盘:0=驱动器A,1=驱动器B,...
硬盘:80h=驱动器1,81h=驱动器2,...
ES:BX = 数据区中I/O缓冲区的地址(除检验操作外)

 

下面是本程序源代码:

;--------------------------------------------------------------------------------------------------------
      ; by Loomman, QQ:28077188, MSN: Loomman@hotmail.com QQ裙:30515563
      ; BiosRd.asm
      ;--------------------------------------------------------------------------------------------------------

  1. data segment
  2.     Buffer      db  512 dup(' ')
  3.     EndCode     db  0
  4.     CurrentAddr dw  0304h       ;beginning track/sector
  5.     EndAddr     dw  0501h       ;Ending track/sector
  6.     ReadErrorMsg    db  'Read error!'
  7.     Side        db  0
  8.     User        db  1, 1 dup(?) ;user input
  9. data ends
  10. code segment
  11.     assume  cs:code, ds:data
  12. main proc near
  13. start:
  14.     push    ds
  15.     sub ax, ax
  16.     push    ax
  17.     mov ax, data
  18.     mov ds, ax
  19.     mov     es, ax
  20.     mov ax, 0600h           ;request scroll
  21. @Continue:
  22.     call    ScrollScreen            ;Scroll screen
  23.     call    SetCursor           ;set cursor
  24.     call    CalcNextDiskAddr        ;calculate next disk address
  25.     mov cx, CurrentAddr         
  26.     mov dx, EndAddr         
  27.     cmp cx, dx              ;is at ending sector?
  28.     je  @Exit               ;yes, exit
  29.     call    ReadDiskRecord          ;read disk record
  30.     cmp EndCode, 0          ;normal read?
  31.     jnz @Exit               ;no, exit
  32.     call    DisplaySector           ;display sector content
  33.     jmp @Continue
  34. @Exit:
  35.     ret
  36. main endp
  37. ;calculate next disk address
  38. CalcNextDiskAddr proc near
  39.     mov cx, CurrentAddr         ;get track/sector
  40.     cmp cl, 10              ;pass last sector
  41.     jne @CNDAExit           ;no, exit
  42.     cmp Side, 0             ;bypass if Side = 0
  43.     je  @ChangeSide         
  44.     inc ch
  45. @ChangeSide:
  46.     xor Side, 1             ;change Side
  47.     mov al, 1               ;set sector to 1
  48.     mov CurrentAddr, cx
  49. @CNDAExit:
  50.     ret
  51. CalcNextDiskAddr endp
  52. ;OUTPUT:
  53. ;AL = 实际读取的扇区数
  54. ReadDiskRecord proc near
  55.     mov ah, 2               ;request read
  56.     mov al, 1               ;one sector
  57.     lea bx, Buffer          ;input buffer at ES:BX
  58.     mov cx, CurrentAddr         ;track/sector
  59.     mov dh, Side            ;head 0
  60.     mov dl, 0               ;drive A(Floopy A)
  61.     int 13h             ;call BIOS
  62.     cmp ah, 0               ;normal read?
  63.     jz  @IncreaseSector         ;yes, exit
  64.     mov     EndCode, 1          ;no
  65.     call    ShowErrorMsg            ;invlaid read
  66. @IncreaseSector:
  67.     inc CurrentAddr         ;increase sector
  68.     ret
  69. ReadDiskRecord endp
  70. ;display sector
  71. DisplaySector proc near
  72.     mov ah, 40h             ;request display
  73.     mov bx, 1               ;handle
  74.     mov cx, 512             ;length
  75.     lea dx, Buffer          ;address of input
  76.     int 21h
  77. @Wait:
  78.     mov ah, 0ah             ;user input
  79.     lea dx, User
  80.     int 21h
  81.     cmp User+1, 0dh
  82.     je  @Wait               ;wait until user input return
  83.     ret
  84. DisplaySector endp
  85. ;clear screen
  86. ScrollScreen proc near
  87.     mov ax, 0600h           ;full screen
  88.     mov bh, 1eh             ;set color
  89.     mov cx, 0               ;request scroll
  90.     mov dx, 184fh
  91.     int 10h
  92.     ret
  93. ScrollScreen endp
  94. ;set cursor
  95. SetCursor proc near
  96.     mov ah, 02              ;request set cursor
  97.     mov bh, 0
  98.     mov dx, 0
  99.     int 10h
  100.     ret
  101. SetCursor endp
  102. ;disk error function
  103. ShowErrorMsg proc near
  104.     mov ah, 40h             ;request display
  105.     mov bx, 1               ;handle
  106.     mov cx, 11              ;length of message
  107.     lea dx, ReadErrorMsg
  108.     int 21h
  109.     ret
  110. ShowErrorMsg endp
  111. code ends
  112.     end start

makefile文件内容如下:

  1. #NMAKE工具的描述文件
  2. NAME = BiosRd           #指定输出文件
  3. EXE = $(NAME).exe           #需要的EXE文件
  4. OBJ = $(NAME).obj           #需要的OBJ文件
  5. LST = $(NAME).lst           #可选的LST文件
  6. CRF = $(NAME).crf           #可选的CRF文件
  7. MAP = $(NAME).map                   #可选的MAP文件
  8. LIB = NUL.lib           #可选的LIB文件
  9. LINK_FLAG = ,$(EXE),$(MAP),,$(LIB)  #链接选项
  10. ML_FLAG   = $(OBJ) $(LST) $(CRF)    #编译选项
  11. #定义依赖关系和执行命令
  12. $(EXE): $(OBJ)
  13.     Link $(OBJ) $(LINK_FLAG)
  14. #定义汇编编译和资源编译得默认规则
  15. .asm.obj:
  16.     masm $< $(ML_FLAG)
  17. #清除临时文件
  18. clean:
  19.     del *.MAP
  20.     del *.CRF
  21.     del *.LST
  22.     del *.OBJ
  23.     del *.BAK
  24.     del *.SBR

本程序采用MASM5(或高于此版本)下配合NMAKE编译和链接, 程序已编译通过, 有何问题欢迎联系。by Loomman, QQ:28077188, MSN: Loomman@hotmail.com QQ裙:30515563 ☆程序天堂☆ 请尊重作者原创,转载注明来自裂帛一剑博客,谢谢合作。

 

 

抱歉!评论已关闭.