在 x86 实模式(16位) 下,可以使用 BIOS 中断 INT 0x13 来读取硬盘数据。以下是详细步骤和示例代码:
1. 硬盘读取原理(CHS/LBA模式)
(1) CHS(柱面-磁头-扇区)模式
-
参数:
-
柱面(Cylinder):
CL(低6位) +CH(完整8位) -
磁头(Head):
DH -
扇区(Sector):
CL(高2位)
-
柱面(Cylinder):
-
限制:
- 最大支持 8GB(1024柱面 × 256磁头 × 63扇区 × 512字节)。
(2) LBA(逻辑块寻址)模式
-
参数:
- LBA 地址:28位(最大支持 128GB)。
- 使用
INT 0x13扩展功能(AH=0x42)。
2. BIOS 中断 INT 0x13 功能
| 功能号(AH) | 功能 | 参数 |
|---|---|---|
AH=0x02 |
读扇区(CHS) |
AL=扇区数, CH=柱面, CL=扇区, DH=磁头, DL=驱动器号, ES:BX=缓冲区
|
AH=0x42 |
读扇区(LBA) |
DL=驱动器号, DS:SI=磁盘地址包(DAP)
|
3. 示例代码(CHS模式读取扇区)
以下代码演示如何 读取硬盘的第一个扇区(MBR) 到内存 0x7E00:
org 0x7C00 ; 引导扇区加载到 0x7C00
bits 16
start:
mov ax, 0x07C0
mov ds, ax ; 设置数据段
mov es, ax ; 设置附加段(用于缓冲区)
; 读取硬盘扇区(CHS模式)
mov ah, 0x02 ; 功能号:读扇区
mov al, 1 ; 读取1个扇区
mov ch, 0 ; 柱面0
mov cl, 1 ; 扇区1(注意:扇区从1开始)
mov dh, 0 ; 磁头0
mov dl, 0x80 ; 驱动器号(0x80=第一块硬盘)
mov bx, 0x7E00 ; ES:BX = 目标缓冲区(0x7E00)
int 0x13 ; 调用BIOS中断
jc error ; 如果CF=1,表示出错
; 成功读取后,数据在 0x7E00
jmp success
error:
mov si, err_msg
call print_string
hlt
success:
mov si, succ_msg
call print_string
hlt
print_string:
lodsb ; 加载字符到AL
or al, al ; 检查是否结束(AL=0)
jz .done
mov ah, 0x0E ; BIOS打印字符功能
int 0x10
jmp print_string
.done:
ret
err_msg db "Error reading disk!", 0
succ_msg db "Disk read success!", 0
times 510-($-$$) db 0
dw 0xAA55 ; MBR签名
4. 示例代码(LBA模式读取扇区)
LBA模式需要 磁盘地址包(DAP),支持更大容量的硬盘:
org 0x7C00
bits 16
start:
mov ax, 0x07C0
mov ds, ax
mov es, ax
; 设置DAP(Disk Address Packet)
mov si, dap
mov ah, 0x42 ; 功能号:扩展读(LBA)
mov dl, 0x80 ; 驱动器号(0x80=第一块硬盘)
int 0x13
jc error
jmp success
dap:
db 0x10 ; DAP大小(16字节)
db 0 ; 保留
dw 1 ; 扇区数
dw 0x7E00 ; 目标偏移(ES:BX)
dw 0 ; 目标段(ES)
dd 0 ; LBA低32位(从0开始)
dd 0 ; LBA高32位(支持48位LBA)
error:
mov si, err_msg
call print_string
hlt
success:
mov si, succ_msg
call print_string
hlt
print_string:
lodsb
or al, al
jz .done
mov ah, 0x0E
int 0x10
jmp print_string
.done:
ret
err_msg db "Error reading disk!", 0
succ_msg db "Disk read success!", 0
times 510-($-$$) db 0
dw 0xAA55
5. 关键注意事项
-
驱动器号:
-
0x80= 第一块硬盘 -
0x81= 第二块硬盘
-
-
扇区编号:
- CHS模式下,扇区从1开始(不是0)。
-
缓冲区对齐:
- 确保
ES:BX指向的缓冲区 不跨越64KB边界。
- 确保
-
错误处理:
- 检查
CF(进位标志),如果CF=1,表示出错(错误代码在AH)。
- 检查
6. 进阶优化
- 使用 LBA48:支持更大硬盘(需检测 BIOS 是否支持)。
- DMA 传输:提高读取速度(需切换保护模式)。
- 保护模式读取:通过 ATA PIO 直接与硬盘控制器通信。
如果需要更高级的硬盘操作(如写入、分区表解析),可以进一步探讨!










网友评论