操作系统学习7 x86架构使用INT13中读取软盘数据

在这里插入图片描述

一、本章使用工具

  • nasm
  • FloppyWriter
  • bochs

二、软盘存储介绍

软盘是一种传统的可移动存储介质,通常用于存储和传输小型数据文件。下面是关于软盘存储介质的详细介绍:

1. 物理结构

  • 软盘通常是一个方形的塑料片,内部覆盖着一层磁性材料。
  • 软盘的尺寸通常为3.5英寸或5.25英寸,常见的尺寸是3.5英寸。
  • 软盘的外壳通常由塑料材料制成,具有一侧的开槽,允许读写磁头进入内部磁介质。
  • 在软盘内部,磁性涂层被分成多个同心圆磁道,每个磁道表示一个柱面。

2. 存储容量

  • 1.44MB 软盘是最常见的软盘规格,也是最常用的。
  • 1.44MB 软盘通常有两面,每一面都可以独立地写入数据。
  • 每个面通常有 80 个柱面,柱面编号从0开始。
  • 每个柱面通常由 18 个扇区组成,扇区编号从1开始。
  • 每个扇区可以存储 512 字节的数据。

3. 数据存储

  • 软盘通过在磁介质上磁化来存储数据。磁化方向的不同代表着二进制数据的 0 和 1。
  • 每个扇区都有一个标识符,用于指示其在磁盘上的位置和数据结构。
  • 读写软盘数据通常需要磁头(磁头)来在磁介质上移动,并读取或写入数据。

4. 使用限制

  • 软盘存储容量相对较小,速度较慢,并且容易受到磁场干扰而损坏。
  • 由于技术进步,软盘逐渐被更先进的存储介质所取代,如USB闪存驱动器、CD/DVD和云存储等。

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

三、BIOS int13功能

1. 基本功能

BIOS 中的 INT 13h 功能是用于磁盘操作的中断服务例程。它提供了一系列功能,允许程序对磁盘进行读取和写入操作。下面是 INT 13h 中一些常见的功能:

  1. 读取扇区

    • 功能号:0x02
    • 输入参数:要读取的扇区数、起始柱面号、起始磁头号、起始扇区号、驱动器号等。
    • 输出参数:读取的数据存储在指定的缓冲区中。
  2. 写入扇区

    • 功能号:0x03
    • 输入参数:要写入的扇区数、起始柱面号、起始磁头号、起始扇区号、驱动器号等。
    • 输出参数:将要写入的数据存储在指定的缓冲区中。
  3. 获取驱动器参数

    • 功能号:0x08
    • 输入参数:驱动器号。
    • 输出参数:返回驱动器的参数,如扇区大小、扇区数、磁头数、柱面数等。
  4. 磁盘重置

    • 功能号:0x00
    • 输入参数:驱动器号。
    • 输出参数:执行磁盘重置操作。
  5. 磁盘类型检测

    • 功能号:0x15
    • 输入参数:驱动器号。
    • 输出参数:返回驱动器的类型,如软盘、硬盘、CD-ROM 等。
  6. 检测扩展功能

    • 功能号:0x41
    • 输入参数:某些其他参数。
    • 输出参数:返回是否支持扩展功能。

这些功能允许操作系统或引导加载程序与硬盘进行交互,执行读取、写入、初始化等操作,以便加载操作系统内核、文件系统或其他必要的数据。

INT 13h 功能是 BIOS 中的一个重要功能,为硬盘操作提供了底层接口,使得软件可以直接与硬盘进行通信。

2. 入口参数:

  • 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)= 出错代码

3. 一段写磁盘示例

读屏幕到软盘上,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

4. 一段读磁盘示例

读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

四、引导程序源代码

1. 源代码

  • 下面源代码带读磁盘的功能,把磁盘数据加载到内存的 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,
    ; 通常在实模式下,段地址(Segment Address)与物理地址(Physical Address)的计算方式是将段地址左移 4 位(相当于乘以 16),然后加上偏移地址(Offset Address)。
    ; 这里 ES 寄存器的值是一个段地址,移动 0x0020 实际上移动了 0x20 * 16 = 0x200 即 512 个字节。
    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<CYLS , 则跳到readloop

    JMP     success

print:   ; 字符串显示到屏幕
   MOV   AL, [SI]      ; 将 SI 寄存器指向的内存地址处的值(即字符串中的一个字符)加载到 AL 寄存器
   ADD   SI, 1         ; 将 SI 寄存器的值增加 1,指向字符串中的下一个字符
   CMP   AL, 0
   JE    end                 ; 如果 AL 寄存器中的值为 0,说明字符串结束,跳转到标签 end
   MOV   AH, 0x0e     ; 指示 BIOS 以特定的文本模式显示字符
   MOV   BX, 15         ; 特定的显示模式,这里表示白色前景和黑色背景的属性值
   INT   0x10
   JMP   print

end:
   HLT
   JMP end             ; 无限循环

error:                 ; 打印错误信息
   MOV SI, error_msg
   JMP print

success:
   MOV SI, success_msg
   JMP print

BootMessage:   
   DB "Hello, MY OS!"   ; 想要开机后在屏幕上显示的字符串
   DB 0
success_msg: 
   DB "Success"         ; 成功
   DB 0
error_msg:    
   DB "Error"           ; 失败
   DB 0

   times  510-($-$$) db 0 ; 填充剩下的空间,使生成的二进制代码恰好为512字节 $$表示一个section的开始处汇编后地址
   DW  0xaa55           ; 结束标志

2. 运行

使用前文方式加载程序:

  1. 编译:
nasm boot.asm -o boot.bin
  1. 使用FloppyWrite.exe 制作 image。
  2. 使用 Bochs加载程序。

在这里插入图片描述

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

编程圈子

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值