30天自制OS学习笔记 (二)汇编语言学习与Makefile入门
(二)汇编语言学习与Makefile入门
上一节中helloos.nas中的代码继续用汇编语言改写:
; hello-os
; TAB=4
ORG 0x7c00 ;指明程序的装载地址
; 以下这段是标准FAT12格式软盘专用的代码
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扇区)
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-$ ;
DB 0x55, 0xaa
helloos.nas的后半部分代码砍掉了,因为要制作启动区只需要前512字节,所以上述代码段的文件名字也改为了ipl.nas
ORG指令会告诉nask,在程序运行时将这些指令装载到内存的那个地址,另外有了这条指令,$的含义不再是指输出文件的第几个字节,而是代表将要读入的内存地址。
entry是标签的声明,用于指定JMP指令的跳转目的地等。
HLT是让CPU停止动作的指令,不过并不是彻底的停止,而是让CPU进入待机状态,只要外部发生变化,比如按下键盘或移动鼠标,CPU就会醒过来。
INT是软件中断指令,源于interrupt 电脑里有个名为BIOS(basic input output system)的程序,出厂时就租装在电脑主板上的ROM(read only memory)单元里,为操作系统开发人员准备的各种函数操作的集合,而INT就是用来调用这些函数的指令,INT后面跟一个数字,使用不同的数字调用不同的函数。内存的0号地址,最开始的那部分,是BIOS用来实现各种不同功能的地方,不能随便使用,另外在内存的0xf0000号地址附近,还放着BIOS程序本身,也是不能用的。
CPU里有一种名为寄存器的存储电路,相当于机器语言中的变量。具有代表性的寄存器有以下8个:(16位,X是扩展的意思,之前寄存器是8位的)
即使这个八个寄存器全加起来,CPU也仅仅存储16个字节。
段寄存器(segment register,16位):
可以用寄存器指定内存地址的寄存器非常有限,只有BX,BP,SI,DI。
一些汇编语言的知识:
关于Makefile
Makefile就像一个非常聪明的批处理文件,需要调用make.exe让Makefile发挥作用,它是和 make 命令一起配合使用的。
Makefile基本格式如下:
target … : prerequisites …
command
…
…
其中,
target - 目标文件, 可以是 Object File, 也可以是可执行文件
prerequisites - 生成 target 所需要的文件或者目标
command - make需要执行的命令 (任意的shell命令), Makefile中的命令必须以 [tab] 开头
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
img :
../z_tools/make.exe -r helloos.img
run :
../z_tools/make.exe img
copy helloos.img ..\z_tools\qemu\fdimage0.bin
../z_tools/make.exe -C ../z_tools/qemu
install :
../z_tools/make.exe img
../z_tools/imgtol.com w a: helloos.img
clean :
-del ipl.bin
-del ipl.lst
src_only :
../z_tools/make.exe clean
-del helloos.img