30天自制操作系统-第二天-OS启动程序优化
汇编程序解释
作者将汇编程序改成更通俗易懂的形式了,我来解释一下
; hello-os
; TAB=4
ORG 0x7c00 ; 指明程序装载地址
; 标准FAT12格式软盘专用的代码 Stand FAT12 format floppy code
JMP entry
DB 0x90
DB "HELLOIPL" ; 启动扇区名称(8字节)
DW 512 ; 每个扇区(sector)大小(必须512字节)
DB 1 ; 簇(cluster)大小(必须为1个扇区)
DW 1 ; FAT起始位置(一般为第一个扇区)
DB 2 ; FAT个数(必须为2)
DW 224 ; 根目录大小(一般为224项)
DW 2880 ; 该磁盘大小(必须为2880扇区1440*1024/512)
DB 0xf0 ; 磁盘类型(必须为0xf0)
DW 9 ; FAT的长度(必??9扇区)
DW 18 ; 一个磁道(track)有几个扇区(必须为18)
DW 2 ; 磁头数(必??2)
DD 0 ; 不使用分区,必须是0
DD 2880 ; 重写一次磁盘大小
DB 0,0,0x29 ; 意义不明(固定)
DD 0xffffffff ; (可能是)卷标号码
DB "HELLO-OS " ; 磁盘的名称(必须为11字?,不足填空格)
DB "FAT12 " ; 磁盘格式名称(必??8字?,不足填空格)
RESB 18 ; 先空出18字节
; 程序主体
entry:
MOV AX,0 ; 初始化寄存器
MOV SS,AX
MOV SP,0x7c00
MOV DS,AX
MOV ES,AX
MOV SI,msg
putloop:
MOV AL,[SI]
ADD SI,1 ; 给SI加1
CMP AL,0
JE fin
MOV AH,0x0e ; 显示一个文字
MOV BX,15 ; 指定字符颜色
INT 0x10 ; 调用显卡BIOS
JMP putloop
fin:
HLT ; 让CPU停止,等待指令
JMP fin ; 无限循环
msg:
DB 0x0a, 0x0a ; 换行两次
DB "hello, world"
DB 0x0a ; 换行
DB 0
RESB 0x7dfe-$ ; 填写0x00直到0x001fe
DB 0x55, 0xaa
ORG 0x7c00
告诉汇编器,程序被加载在内存中0x7c00开始的位置了,后续的偏移命令都要以这个为基础
JMP entry
这里就比较清晰了,跳转到entry代码段。因为程序被加载到内存后,CPU也不知道哪是数据段,哪是代码段,跳转执行,等同于JMP 0x7c50
MOV SI,msg
将msg对应的内存地址0x7c74,赋值SI寄存器
MOV AL,[SI]
MOV AL, BYTE [SI],将SI地址的1字节内容读入AL
CMP AL,0
判断AL是否为0,类似于判断C语言中字符串末尾'\0'标识
JE fin
上一条件成立则跳转
INT 0x10
10中断API,AH=0x0e;AL=character code;BH=0;BL=color code;返回值:无
JMP putloop
循环打印所有字符
DB 0
手动写0,对应CMP AL,0
Makefile简介
# 默认动作
default :
../z_tools/make.exe img
# 镜像文件生成
ipl.bin : ipl.nas Makefile
../z_tools/nask.exe ipl.nas ipl.bin ipl.lst
helloos.img : ipl.bin Makefile
../z_tools/edimg.exe imgin:../z_tools/fdimg0at.tek \
wbinimg src:ipl.bin len:512 from:0 to:0 imgout:helloos.img
# 其他指令
asm :
../z_tools/make.exe -r ipl.bin
初步了解一下,执行make时就会读取Makefile配置文件,不熟悉地方主要在文件依赖规则那里。“ipl.bin : ipl.nas Makefile”的意思是,如果想要制作文件ipl.bin,就先检查一下ipl.nas和Makefile这两个文件是否都准备好了。而且当源文件更新时,会检查文件修改日期重新生成