《30天自制操作系统》学习笔记——第1-3天

来源:互联网 发布:淘宝店被关闭 编辑:程序博客网 时间:2024/05/22 20:30

这本书作者是日本人,虽然书翻译为中文,但是源代码里注释都是日文,对不懂日语的人来说看起来不够方便,我把书本中给出的注释翻译,以及书本介绍的一些知识,加到了注释里,阅读起来能够方便些。
前3天主要就是写一个ipl程序(initial program loader启动程序加载器),不论是用二进制编辑器直接写机器指令还是用汇编生成二进制程序,最终目的都是得到第一个扇区的512字节的启动程序。

0x10号bios函数用于显示文字

0x13号bios函数提供磁盘的读,写,扇区校验,寻道操作,AH=0x02读盘操作

这两个bios函数调用时以寄存器的值为参数,提供相应操作。


; haribote-ipl; TAB=4CYLS  EQU10;ORG0x7c00;ORG伪指令,编译不生成机器代码,用于给链接器定位用,将程序装载到内存的指定位置;0x7c00~0x7dff 512字节放置启动程序; 标准FAT12格式软盘专用的代码JMPentry;jmp跳转 至标签entry处;JMP 0x7c50 没问题,JMP跳转到的就是内存地址DB0x90;DB即data byte 往文件里写入一个字节,DW写一个word,16位,DD写double word,32位DB"HARIBOTE";启动区的名称,可以是任意的字符串(8字节)DW512;每个扇区(sector)的大小(必须为 512字节)DB1;簇(cluster)的大小(必须为 1 个扇区)DW1;FAT(File Allocation Table:文件配置表)的起始位置(一般从第一个扇区开始)DB2;FAT的个数,必须为2 DW224;根目录的大小(一般设成224项)DW2880;该磁盘的大小(必须为2880个扇区)DB0xf0;磁盘的种类(必须为0xf0)DW9;FAT的长度(必须是9扇区) DW18;一个磁道(track)有几个扇区(必须是18)DW2;磁头数(必须是2)DD0;不使用分区,必须是0DD2880;重写一次磁盘大小 DB0,0,0x29;意义不明,固定DD0xffffffff;(可能是)卷标号码DB"HARIBOTEOS "; 磁盘的名称(11字节)DB"FAT12   "; 磁盘格式名称(8字节)RESB18; reserve word 从当前地址空出18个字节,nask会把这18个字节填充为0x00entry:MOVAX,0 ;AX accumulator 累加寄存器 (16位)把0复制到AX中,初始化AXMOVSS,AX ;SS stack segment栈段寄存器 (16位)MOVSP,0x7c00;SP stack pointer栈指针寄存器(16位)MOVDS,AX ;DS data segment数据段寄存器(16位)MOVAX,0x0820 ;MOV AL,[ES:BX] 代表ES*16+BX的内存地址 ;0x7c00~0x7dff用于启动区,0x7e00~0xfbff没有特别的用途,操作系统随便用;缓冲区地址,将要把软盘上读取的数据放到0x8200之后,内存分布图上0x8000后无人使用;0x8000~0x81ff留给启动区,将启动区内容读到这里MOVES,AX ;ES extra segment附加段寄存器(16位)ES=0x0820,BX=0MOVCH,0 ;CHcounter high    计数寄存器高位(8位)柱面0MOVDH,0 ;DHdata high数据寄存器高位(8位)磁头0MOVCL,2 ;CL counter low计数寄存器地位(8位)扇区2,计数读的扇区标号readloop:MOVSI,0 ;SIsource index源变址寄存器(16位)记录失败retry:MOVAH,0x02 ;AHaccumulator high 累加寄存器高位(8位) AX=0x02 读盘MOVAL,1 ;ALaccumulator low  累加寄存器低位(8位) AL=1 1个扇区MOVBX,0 ;BX base 基址寄存器(16位)MOVDL,0x00  ;DLdata low 数据寄存器低位(8位)A驱动器INT0x13;INT interrupt 软件中断指令,暂且当作函数调用 调用磁盘BIOSJNCnext;jump if not carry 如果进位标志为0,跳转至next0x13调用有错标志为1,无错为0ADDSI,1 ;SI加1CMPSI,5 ;比较SI和5JAEerror ;jump if above or equal SI>=5时跳转到errorMOVAH,0x00 ;MOVDL,0x00 ;A驱动器INT0x13 ;重置驱动器JMPretry ;无条件 跳转到retrynext:MOVAX,ES ;把内存地址后移0x200 512字节 512/16=0x20 [ES:BX]ADDAX,0x0020;MOVES,AX ;没有ADD ES,0x20指令ADDCL,1 ;CL+1CMPCL,18 ;比较CL和18(1-18 18个扇区)JBEreadloop;jump if below or equal cl<=18 跳转到readloop MOVCL,1 ;扇区标号更新为1ADDDH,1 ;磁头数+1,读磁盘反面CMPDH,2 ;比较DH 2JB readloop ;jump if below DH<2 时跳转到readloop MOVDH,0 ;磁头初始化为0ADDCH,1 ;柱面+1CMPCH,CYLS ;比较CH 和 CYLS=10JB readloop ;jump if below  CH<10 跳转到readloop;空软盘保存文件时,文件名会写在0x2600以后的地方,文件内容会写在0x4200以后MOV[0x0ff0],CH ;把磁盘装载地址的结束写到内存0x0ff0处JMP0xc200 ;程序从启动区开始,把磁盘上的内容装载到内存0x8000号地址,磁盘0x4200处的内容应该位于;0x8000+0x4200=0xc200号地址error:MOVSI,msg;msg地址复制到SIputloop:MOVAL,[SI];[]表示内存地址,这句是把内存地址为SI的数据复制到AL中ADDSI,1 ;SI+1CMPAL,0 ;比较AL和0JEfin ;jump if equalMOVAH,0x0e ;MOVBX,15 ;INT0x10 ;调用bios 0x10号函数JMPputloop ;fin:HLT ;CPU停止动作,进入待机状态,外部发生变化,比如按下键盘,cpu会苏醒过来,继续执行程序JMPfin;无限循环msg:DB0x0a,0x0a ;2个换行DB"load error" ;DB直接写字符串,汇编语言自动查找编码DB0x0a;换行DB0 ;标志msg结束RESB0x7dfe-$;$指示当前行在文件中所处的字节数;在使用ORG指令后DB0x55,0xaa;软盘的第0x1fe即第510字节开始处必须为55 aa

1 0
原创粉丝点击