热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

开发日志:磁盘读取技术详解——CHS模式的应用与解析

本文由编程笔记#小编为大家整理,主要介绍了读取磁盘:CHS方式相关的知识,希望对你有一定的参考价值。 读取磁盘:CHS方式Bios读取磁盘读取磁盘也是调用BIOS:中断命令: INT 13H读取扇区的
本文由编程笔记#小编为大家整理,主要介绍了读取磁盘:CHS方式相关的知识,希望对你有一定的参考价值。



读取磁盘:CHS方式


Bios读取磁盘

读取磁盘也是调用BIOS:


中断命令: INT 13H


读取扇区的入口参数为


AH = 02H 功能参数,读取扇区



AL = 扇区数



CH = 柱面



CL = 扇区



DH = 磁头



DL = 驱动器号,00H~7FH:软盘驱动器号;80H~0FFH:硬盘驱动器号



ES:BX = 缓冲区的地址


出口参数


CF = 0: 操作成功,AH = 00H,AL = 传输的扇区数



否则,AH = 状态代码



定义磁盘读取函数

1. 读取一个扇区

; ------------------------------------------------------------------------
; 读取一个扇区函数:ReadDisk0
; ------------------------------------------------------------------------
; 参数:ES:BX 缓冲区地址,CH柱面,DH磁头,CL扇区
; ------------------------------------------------------------------------
ReadDisk0:
MOV SI,0 ;初始化读取失败次数,用于循环计数

;为了防止读取错误,循环读取5次
;调用BIOS读取一个扇区
ReadFiveLoop:
MOV AH,0x02 ;BIOS中断参数:读扇区
MOV AL,1 ;BIOS中断参数:读取扇区数
MOV BX,0
MOV DL,0x00 ;BIOS中断参数:设置读取驱动器为软盘
INT 0x13 ;调用BIOS中断操作磁盘:读取扇区
JNC ReadEnd ;条件跳转,操作成功进位标志=0。则跳转执行ReadNextSector

inc si ;循环读取次数递增+1
CMP SI,5 ;判断是否已经读取超过5次
JAE LoadError ;上面cmp判断(>=)结果为true则跳转到DisplayError

MOV AH,0x00 ;BIOS中断参数:磁盘系统复位
MOV DL,0x00 ;BIOS中断参数:设置读取驱动器为软盘
INT 0x13 ;调用BIOS中断操作磁盘:磁盘系统复位
JMP ReadFiveLoop
;扇区读取完成
ReadEnd:
RET

2. 读取多个扇区

读取时要根据 扇区<磁头<柱面 的方式来读取。继续添加代码,读取18个扇区:(即完整的读取了一个柱面)。

代码如下:

?

3. 读取多个柱面

继续添加代码,读取10个柱面。

?

然后调用函数

;读取磁盘初始化
MOV AX,DISC_ADDR/0x10 ;设置磁盘读取的缓冲区基本地址为ES=0x820。[ES:BX]=ES*0x10+BX
MOV ES,AX ;BIOS中断参数:ES:BX=缓冲区的地址
MOV CH,0 ;设置柱面为0
MOV DH,0 ;设置磁头为0
MOV CL,2 ;设置扇区为2
ReadSectorLoop:
CALL ReadDisk0; ;读取一个扇区

转换LBA到CHS方式读取

; ==============================================
; 读取磁盘:Func_readCHS2LBA
; 参数:
; ebx 扇区逻辑号
; cx 读入的扇区数,8位
; es 读取到内存单元的地址
; ==============================================
.reset
MOV AH,0x00 ;BIOS中断参数:磁盘系统复位
MOV DL,0x00 ;BIOS中断参数:设置读取驱动器为软盘
INT 0x13 ;调用BIOS中断操作磁盘:磁盘系统复位
ret

.readdisk
;初始化读取失败次数,用于循环计数
push cx
MOV cx,5

;为了防止读取错误,循环读取5次
;调用BIOS读取一个扇区
ReadFiveLoop:
MOV AH,0x02 ;BIOS中断参数:读扇区
MOV AL,1 ;BIOS中断参数:读取扇区数
MOV BX,0
MOV DL,0x00 ;BIOS中断参数:设置读取驱动器为软盘
INT 0x13 ;调用BIOS中断操作磁盘:读取扇区
JNC .readok ;条件跳转,操作成功进位标志=0。则跳转执行ReadNextSector

inc si ;循环读取次数递增+1
CMP SI,5 ;判断是否已经读取超过5次
JAE .readfail ;上面cmp判断(>=)结果为true则跳转到DisplayError

call .reset
loop ReadFiveLoop

;准备下一个扇区
.readok:

MOV AX,ES
ADD AX,0x0020
MOV EX,AX ;内存单元基址后移0x20。[EX+0x20:]
ADD CL,1 ;读取扇区数递增+1
CMP CL,18 ;判断是否读取到18扇区
JBE readdisk ;上面cmp判断(<=)结果为true则跳转到DisplayError

.readxx
;读取另一面磁头。循环读取柱面
MOV CL,1 ;设置柱面为0
ADD DH,1 ;设置磁头递增+1:读取下一个磁头
CMP DH,2 ;判断磁头是否读取完毕
JB ReadSectorLoop ;上面cmp判断(<)结果为true则跳转到DisplayError
MOV DH,0 ;设置磁头为0
ADD CH,1 ;设置柱面递增+1;读取下一柱面
CMP CH,10 ;判断是否已经读取10个柱面
JB readdisk ;上面cmp判断(<)结果为true则跳转到DisplayError

完整代码

最后,完整的boot.asm文件代码如下:

;RATSBOOT
;TAB=4

;定义常量
DISC_ADDR EQU 0x8000 ;磁盘第一个扇区开始,加载到内存缓冲的地址
SECTOR_NUM EQU 18 ;读取扇区数
CYLINDER_NUM EQU 10 ;读取柱面数

ORG 0x7c00 ;指明程序的偏移的基地址

;以下这段是标准FAT32 格式软盘专用的代码

JMP Entry

DB 0x90 ;nop,0x02
DB "RATSBOOT" ;(8字节)启动区的名称可以是任意的字符串
DW 512 ;每个扇区(sector)的大小(必须为512 字节)
DB 8 ;簇(cluster )的大小(每个簇为8个扇区)
DW 584 ;保留扇区数,包括启动扇区
DB 2 ;FAT的个数(必须为2)
DW 0 ;最大根目录条目个数
DW 0 ;总扇区数(如果是0,就使用偏移0x20处的4字节值)
DB 0x00f8 ;磁盘介质描述
DW 0 ;(FAT16)每个文件分配表的扇区
DW 63 ;每个磁道扇区数
dw 255 ;磁头数
dd 63 ;隐藏扇区
dd 3902913 ;磁盘大小,总共扇区数(如果超过65535,参见偏移0x13)
dd 3804 ;每个文件分配表的扇区,3804个扇区

dw 0 ;Flagss
dw 0 ;版本号
dd 2 ;根目录启始簇

dw 1 ;FSInfo扇区
dw 6 ;启动扇区备份
times 12 db 0 ;保留未使用

DW 0 ;操作系统自引导代码
db 0x80 ;BIOS设备代号
db 0 ;未使用
db 0x29 ;标记
DD 0xffffffff ;序列号
DB "HELLO-OS " ;(11字节)磁盘名称,卷标。字符串长度固定
DB "FAT32 " ;(8字节)FAT文件系统类型。 0x52

times 12 db 0

;程序核心内容
Entry:
MOV AX,0 ;初始化寄存器
MOV SS,AX
MOV SP,0x7c00
MOV DS,AX

MOV DI,StartMessage ;将Message1段的地址放入SI
CALL DisplayStr ;调用函数
MOV DI,BootMessage ;将Message1段的地址放入SI
ADD DH,1
CALL DisplayStr ;调用函数
;读取磁盘初始化
MOV AX,DISC_ADDR/0x10 ;设置磁盘读取的缓冲区基本地址为ES=0x820。[ES:BX]=ES*0x10+BX
MOV ES,AX ;BIOS中断参数:ES:BX=缓冲区的地址

MOV CH,0 ;设置柱面为0
MOV DH,0 ;设置磁头为0
MOV CL,1 ;设置扇区为2

ReadSectorLoop:
CALL ReadDisk0; ;读取一个扇区

;准备下一个扇区
ReadNextSector:
MOV AX,ES
ADD AX,0x0020
MOV ES,AX ;内存单元基址后移0x20(512字节)。[ES+0x20:]
ADD CL,1 ;读取扇区数递增+1
CMP CL,SECTOR_NUM ;判断是否读取到18扇区
JBE ReadSectorLoop ;上面cmp判断(<=)结果为true则跳转到DisplayError

;读取另一面磁头。循环读取柱面
MOV CL,1 ;设置柱面为0
ADD DH,1 ;设置磁头递增+1:读取下一个磁头
CMP DH,2 ;判断磁头是否读取完毕
JB ReadSectorLoop ;上面cmp判断(<)结果为true则跳转到DisplayError

MOV DH,0 ;设置磁头为0
ADD CH,1 ;设置柱面递增+1;读取下一柱面
CMP CH,CYLINDER_NUM ;判断是否已经读取10个柱面
JB ReadSectorLoop ;上面cmp判断(<)结果为true则跳转到DisplayError

;LoadSuccess:
MOV DI,Succmsg
MOV DH,3
CALL DisplayStr ;此处必须注释掉,不能调用INT。原因不明。

;加载执行boot文件:
;MOV [0x0ff0],CH ;将总共读取的柱面数存储在内存单元中
;JMP 0xc200 ;跳转执行在内存单元0xc200的代码
GoLoader:
MOV [0x0ff0],CH ;将总共读取的柱面数存储在内存单元中
JMP 0xc200 ;跳转执行在内存单元0xc200的代码:DISC_ADDR-0x200+0x4200
;(启动扇区开始地址0x8000+软盘代码:boot文件开始0x4200)

LoadError:
MOV DI,Errormsg
MOV DH,3
CALL DisplayStr ;如果加载失败显示加载错误

;程序挂起
Fin:
HLT ;让CPU挂起,等待指令。
JMP Fin
; ------------------------------------------------------------------------
; 读取一个扇区函数:ReadDisk0
; ------------------------------------------------------------------------
; 参数:ES:BS 缓冲区地址,CH柱面,DH磁头,CL扇区,AL扇区数=1,DL驱动器=0x
; ------------------------------------------------------------------------
ReadDisk0:

MOV SI,0 ;初始化读取失败次数,用于循环计数

;为了防止读取错误,循环读取5次
;调用BIOS读取一个扇区
ReadFiveLoop:

MOV AH,0x02 ;BIOS中断参数:读扇区
MOV AL,1 ;BIOS中断参数:读取扇区数
MOV BX,0
MOV DL,0x00 ;BIOS中断参数:设置读取驱动器为软盘
INT 0x13 ;调用BIOS中断操作磁盘:读取扇区
JNC ReadEnd ;条件跳转,操作成功进位标志=0。则跳转执行ReadNextSector

ADD SI,1 ;循环读取次数递增+1
CMP SI,5 ;判断是否已经读取超过5次
JAE LoadError ;上面cmp判断(>=)结果为true则跳转到DisplayError

MOV AH,0x00 ;BIOS中断参数:磁盘系统复位
MOV DL,0x00 ;BIOS中断参数:设置读取驱动器为软盘
INT 0x13 ;调用BIOS中断操作磁盘:磁盘系统复位
JMP ReadFiveLoop
;扇区读取完成
ReadEnd:
RET

; ------------------------------------------------------------------------
; 显示字符串函数:DisplayStr
; ------------------------------------------------------------------------
; 参数:SI:字符串开始地址, DH为第N行
; ------------------------------------------------------------------------
DisplayStr:
MOV CX,0 ;BIOS中断参数:显示字符串长度
MOV BX,DI
.1:;获取字符串长度
MOV AL,[BX] ;读取1个字节。这里必须为AL
ADD BX,1 ;读取下个字节
CMP AL,0 ;是否以0结束
JE .2
ADD CX,1 ;计数器
JMP .1
.2:;显示字符串
MOV BX,DI
MOV BP,BX
MOV AX,DS
MOV ES,AX ;BIOS中断参数:计算[ES:BP]为显示字符串开始地址

MOV AH,0x13 ;BIOS中断参数:显示文字串
MOV AL,0x01 ;BIOS中断参数:文本输出方式(40×25 16色 文本)
MOV BH,0x0 ;BIOS中断参数:指定分页为0
MOV BL,0x0c ;BIOS中断参数:指定白色字体07
MOV DL,0 ;列号为0
INT 0x10 ;调用BIOS中断操作显卡。输出字符
RET

;数据初始化
StartMessage: DB "hello,rats os start",0
BootMessage: DB "booting............",0
Errormsg: DB "load error ",0
Succmsg: DB "load success",0

FillSector:
RESB 510-($-$$) ;处理当前行$至结束(1FE)的填充
DB 0x55, 0xaa

运行结果如下:

技术分享图片


上面代码的作用

首先boot.asm会被加载到内存并且执行.后面开始读取磁盘的10个柱面(10*18个扇区).
读取的扇区数据复制到 内存 0x8000 开始的位置.
然后打印输出"hello,rats os start"




推荐阅读
  • 结语 | 《探索二进制世界:软件安全与逆向分析》读书笔记:深入理解二进制代码的逆向工程方法
    结语 | 《探索二进制世界:软件安全与逆向分析》读书笔记:深入理解二进制代码的逆向工程方法 ... [详细]
  • Java服务问题快速定位与解决策略全面指南 ... [详细]
  • 作为140字符的开创者,Twitter看似简单却异常复杂。其简洁之处在于仅用140个字符就能实现信息的高效传播,甚至在多次全球性事件中超越传统媒体的速度。然而,为了支持2亿用户的高效使用,其背后的技术架构和系统设计则极为复杂,涉及高并发处理、数据存储和实时传输等多个技术挑战。 ... [详细]
  • 在稀疏直接法视觉里程计中,通过优化特征点并采用基于光度误差最小化的灰度图像线性插值技术,提高了定位精度。该方法通过对空间点的非齐次和齐次表示进行处理,利用RGB-D传感器获取的3D坐标信息,在两帧图像之间实现精确匹配,有效减少了光度误差,提升了系统的鲁棒性和稳定性。 ... [详细]
  • 本文详细介绍了如何在Linux系统中搭建51单片机的开发与编程环境,重点讲解了使用Makefile进行项目管理的方法。首先,文章指导读者安装SDCC(Small Device C Compiler),这是一个专为小型设备设计的C语言编译器,适合用于51单片机的开发。随后,通过具体的实例演示了如何配置Makefile文件,以实现代码的自动化编译与链接过程,从而提高开发效率。此外,还提供了常见问题的解决方案及优化建议,帮助开发者快速上手并解决实际开发中可能遇到的技术难题。 ... [详细]
  • Prim算法在处理稠密图时表现出色,尤其适用于边数远多于顶点数的情形。传统实现的时间复杂度为 \(O(n^2)\),但通过引入优先队列进行优化,可以在点数为 \(m\)、边数为 \(n\) 的情况下显著降低时间复杂度,提高算法效率。这种优化方法不仅能够加速最小生成树的构建过程,还能在大规模数据集上保持良好的性能表现。 ... [详细]
  • PHP中元素的计量单位是什么? ... [详细]
  • 来宾 | Vmware ESXi 平台下的虚拟机在线管理与技术支持
    来宾 | Vmware ESXi 平台下的虚拟机在线管理与技术支持 ... [详细]
  • 开发笔记:STL 容器 deque 的元素访问与迭代器详解
    开发笔记:STL 容器 deque 的元素访问与迭代器详解 ... [详细]
  • 本文作为“实现简易版Spring系列”的第五篇,继前文深入探讨了Spring框架的核心技术之一——控制反转(IoC)之后,将重点转向另一个关键技术——面向切面编程(AOP)。对于使用Spring框架进行开发的开发者来说,AOP是一个不可或缺的概念。了解AOP的背景及其基本原理,对于掌握这一技术至关重要。本文将通过具体示例,详细解析AOP的实现机制,帮助读者更好地理解和应用这一技术。 ... [详细]
  • 从无到有,构建个人专属的操作系统解决方案
    操作系统(OS)被誉为程序员的三大浪漫之一,常被比喻为计算机的灵魂、大脑、内核和基石,其重要性不言而喻。本文将详细介绍如何从零开始构建个人专属的操作系统解决方案,涵盖从需求分析到系统设计、开发与测试的全过程,帮助读者深入理解操作系统的本质与实现方法。 ... [详细]
  • 本文介绍了使用 Python 编程语言高效抓取微博文本和动态网页图像数据的方法。通过详细的示例代码,展示了如何利用爬虫技术获取微博内容和动态图片,为数据采集和分析提供了实用的技术支持。对于对网络数据抓取感兴趣的读者,本文具有较高的参考价值。 ... [详细]
  • 本文详细解析了 MySQL 5.7.20 版本中二进制日志(binlog)崩溃恢复机制的工作流程。假设使用 InnoDB 存储引擎,并且启用了 `sync_binlog=1` 配置,文章深入探讨了在系统崩溃后如何通过 binlog 进行数据恢复,确保数据的一致性和完整性。 ... [详细]
  • 全面解析:Hadoop技术栈中的Linux操作系统概览
    全面解析:Hadoop技术栈中的Linux操作系统概览 ... [详细]
  • MySQL性能优化与调参指南【数据库管理】
    本文详细探讨了MySQL数据库的性能优化与参数调整技巧,旨在帮助数据库管理员和开发人员提升系统的运行效率。内容涵盖索引优化、查询优化、配置参数调整等方面,结合实际案例进行深入分析,提供实用的操作建议。此外,还介绍了常见的性能监控工具和方法,助力读者全面掌握MySQL性能优化的核心技能。 ... [详细]
author-avatar
我爱我19930515
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有