学习x86汇编语言7 使用INT13读取软盘数据

学习x86汇编语言7 使用INT13读取软盘数据

  • 一、本章使用工具
  • 二、软盘存储介绍
  • 三、BIOS int13功能
  • 四、引导程序源代码

一、本章使用工具

  • nasm
  • FloppyWriter
  • bochs

二、软盘存储介绍

  • 1.44M的软盘有2面
  • 每面80个柱面
  • 一个柱面18个扇区
  • 每个扇区有512字节

总容量: 280 × 18 × 512 = 1474560 ( 字 节 ) 280 \times 18 \times 512=1474560(字节) 280×18×512=1474560()

三、BIOS int13功能

BIOS的int13 中断是扩展的磁盘读取功能。
入口参数:

  • ah= int 13H 的功能号(2表示读扇区、3表示写扇区)
  • al= 读取/写入的扇区数
  • ch= 磁道号
  • cl= 扇区号
  • dh= 磁头号(对于软盘即面号,对软盘一个面用一个磁头来读写)
  • dl= 驱动器号 软驱从0开始,0:软驱A 、 1:软驱B
    硬盘从80H开始,80H:硬盘C 、 81H: 硬盘D

es:bx 指向接收从扇区读入数据的内存区/指向将写入磁盘的数据

返回参数:

  • 操作成功,(ah)= 0 ,(al)= 读取/写入的扇区数
  • 操作失败,(ah)= 出错代码

一段写磁盘示例
读屏幕到软盘上,1屏4000Byte,使用8个扇区,使用磁盘的0面0道1~8扇区存储。

assume cs:code
code segment
    start:  mov ax,0B800h
            mov es,ax
            mov bx,0
            
            mov al,8
            mov ch,0
            mov cl,1
            mov dl,0
            mov dh,0
            mov ah,3
            int 13h
            
            mov ax,4c00h
            int 21H
    code ends
    end start

一段读磁盘示例
读0面0道1扇区到 0000:0200H

assume cs:code
code segment
    start:  mov ax,0
            mov es,ax
            mov bx,200H
            
            mov al,1
            mov ch,0
            mov cl,1
            mov dl,0
            mov dh,0
            mov ah,2
            int 13h
            
            mov ax,4c00h
            int 21H
    code ends
    end start

四、引导程序源代码

  • 带读磁盘的功能,把磁盘数据加载到内存的 0x0820处。
  • 从第2个扇区开始读,因为第一个扇区给启动程序用了。
;%define _BOOT_DEBUG_   ; 做Boot Sector时把这行注释掉
						      ; 启用这行就用nasm Boot.asm -o Boot.com生成.com文件用于调试
						
%ifdef _BOOT_DEBUG_
   org  0100h
%else
   org 07c00h
%endif

CYLS EQU 10

init:
   MOV AX,0
   MOV SS,AX
   MOV SP,0x7c00        ; 堆栈空间,从0x7c00向前
   MOV DS,AX
   MOV AX,0x0820        ; 把磁盘数据加载到内存0x0820处。 0x8000~0x81ff的512字节给启动区用的,所以从0x0820开始
   MOV ES,AX            ; 初始化磁盘接口
   MOV CH,0             ; 柱面 0
   MOV DH,0             ; 磁头 0
   MOV CL,2             ; 扇区 2

readloop:
   MOV SI,0             ; 记录失败次数

retry:
   MOV    AH,0x02       ; 0x02 读磁盘
   MOV    AL,1          ; 读1个扇区
   MOV    BX,0
   MOV    DL,0x00       ; A驱动器

   INT    0x13          ; BIOS 读磁盘功能
   JNC    next          ; 成功跳转

   ADD    SI,1          ; 失败加一次
   CMP    SI,5          ; 到5次就跳到error
   JAE    error
   MOV    AH,0x00       ; 复位磁盘功能
   MOV    DL,0x00
   INT    0x13          ; 重置磁盘驱动器
   JMP    retry         ; 重试
   
next:
    MOV     AX,ES       ; 内存地址向后移动0x0020
    ADD     AX,0x0020   
    MOV     ES,AX       ; 通过AX给ES加0x0020

    ADD     CL,1        ; 扇区+1
    CMP     CL,18       ; 有没有到18个扇区
    JBE     readloop    ; CL<=18,就跳到 readloop
    
    MOV     CL,1
    ADD     DH,1
    CMP     DH,2
    JB     readloop    ; 如果 DH < 2 ,则跳到readloop
    
    MOV     DH,0
    ADD     CH,1
    CMP     CH,CYLS
    JB     readloop    ; 如果CH

你可能感兴趣的:(#,操作系统)