上次说到文件操作,今天要真正操作文件了
补充:
之前忘讲了,汇编语言没有缩进,不 tab 也行
有人问我 Linux 系统怎么编译,Linux 下载 nasm 就行了,Cygwin 本来就是为了 Windows 模拟 Linux 终端,dd 和 cat 命令本身就是 Linux 命令,直接在终端输入就行了
我们这个教程主要是做 16 位的操作系统,BIOS 提供的功能足够了,但后期也会讲到 32 位
一、关于软盘
文件操作其实就是读软盘的信息,先来了解一下软盘:
软盘分了两个磁头(面),每个磁头有18 个扇区,每个扇区有 80 个柱面(0-79)
看一下磁盘操作:
磁盘读、写,扇区校验(verify),以及寻道(seek)
AH=0x02;(读盘)
AH=0x03;(写盘)
AH=0x04;(校验)
AH=0x0c;(寻道)
AL=处理对象的扇区数;(只能同时处理连续的扇区)
CH=柱面号 &0xff;
CL=扇区号(0-5位)|(柱面号&0x300)* * 2;
DH=磁头号;
DL=驱动器号;
ES:BX=缓冲地址;(校验及寻道时不使用)
返回值:
FLACS.CF==0:没有错误,AH==0
FLAGS.CF==1:有错误,错误号码存入AH内(与重置(reset)功能一样)
-----------------------------------
综上所述,1张软盘有80个柱面,2个磁头,18个扇区,且一个扇区有512字节。所以,一张软盘的容量是:
80×2×18×512 = 1,474,560 Byte = 1,440KB
我们引导扇区的容量就是 512 字节
二、代码实现
下面是代码实现
CYLS EQU 10
ORG 0x7c00
JMP entry
DB 0x90
DB "HANOS "
DW 512
DB 1
DW 1
DB 2
DW 224
DW 2880
DB 0xf0
DW 9
DW 18
DW 2
DD 0
DD 2880
DB 0,0,0x29
DD 0xffffffff
DB "HANOS "
DB "FAT12 "
RESB 18
entry:
MOV AX,0
MOV SS,AX
MOV SP,0x7c00
MOV DS,AX
MOV AX,0x0820
MOV ES,AX
MOV CH,0
MOV DH,0
MOV CL,2
readloop:
MOV SI,0
retry:
MOV AH,0x02
MOV AL,1
MOV BX,0
MOV DL,0x00
INT 0x13
JNC next
ADD SI,1
CMP SI,5
JAE error
MOV AH,0x00
MOV DL,0x00
INT 0x13
JMP retry
next:
MOV AX,ES
ADD AX,0x0020
MOV ES,AX
ADD CL,1
CMP CL,18
JBE readloop
MOV CL,1
ADD DH,1
CMP DH,2
JB readloop
MOV DH,0
ADD CH,1
CMP CH,CYLS
JB readloop
MOV [0x0ff0],CH
JMP 0xc200
error:
MOV SI,msg
putloop:
MOV AL,[SI]
ADD SI,1
CMP AL,0
JE fin
MOV AH,0x0e
MOV BX,15
INT 0x10
JMP putloop
fin:
HLT
JMP fin
msg:
DB 0x0a, 0x0a
DB "load error"
DB 0x0a
DB 0
RESB 0x7dfe-$
DB 0x55, 0xaa
保存到 ipl.asm
hanos 要改一下,把第一行和最后两行删掉!!!
用 nasm 编译
nasm ipl.asm -o ipl.bin
nasm hanos.asm -o hanos.bin
打开 Cygwin.bat
cat ipl.bin hanos.bin > hanos.img
运行一下
一切正常
再也不怕超过 512 字节了
三、实现真正的文件操作
跟 ipl 同理
CYLS EQU 10
JMP entry
DB 0x90
DB "HANOS "
DW 512
DB 1
DW 1
DB 2
DW 224
DW 2880
DB 0xf0
DW 9
DW 18
DW 2
DD 0
DD 2880
DB 0,0,0x29
DD 0xffffffff
DB "HANOS "
DB "FAT12 "
RESB 18
entry:
MOV AX,0
MOV SS,AX
MOV SP,0x7c00
MOV DS,AX
MOV AX,0x0820
MOV ES,AX
MOV CH,0
MOV DH,0
MOV CL,2
readloop:
MOV SI,0
retry:
MOV AH,0x02
MOV AL,1
MOV BX,0
MOV DL,0x00
INT 0x13
JNC next
ADD SI,1
CMP SI,5
JAE error
MOV AH,0x00
MOV DL,0x00
INT 0x13
JMP retry
next:
MOV AX,ES
ADD AX,0x0020
MOV ES,AX
ADD CL,1
CMP CL,18
JBE readloop
MOV CL,1
ADD DH,1
CMP DH,2
JB readloop
MOV DH,0
ADD CH,1
CMP CH,CYLS
JB readloop
MOV [0x0ff0],CH
JMP 0xc200
error:
MOV SI,msg
putloop:
MOV AL,[SI]
ADD SI,1
CMP AL,0
JE fin
MOV AH,0x0e
MOV BX,15
INT 0x10
JMP putloop
fin:
HLT
JMP fin
msg:
DB 0x0a, 0x0a
DB "load error"
DB 0x0a
DB 0
这里不是完整代码,需要读者自行修改,就能实现真正的文件操作了。
我懒得写了