一个操作系统启动区的汇编程序

来源:互联网 发布:省市区镇四级联动sql 编辑:程序博客网 时间:2024/06/08 08:32

来自《30天自制操作系统》

程序以二进制形式存储在启动盘的第一个扇区,系统启动时,bios自动读入启动盘的第一个扇区,检测其最后两个字节,发现是0x55和0xaa,表面该扇区是启动扇区,于是载入该扇区的程序,放到0x7c00的内存位置(操作系统的启动区皆放于此),然后如程序所示,载入操作系统所在的扇区后,跳转到操作系统所在的内存开始执行···


; haribote-ipl; TAB=4CYLSEQU10; 读入的柱面个数ORG0x7c00; 载入内存的位置; 以下这段是表中FAT12格式软盘专用的代码JMPentryDB0x90DB"HARIBOTE"; 启动区的名字可以使人员字符串DW512; 每个扇区的大小(512个字节)DB1; 簇的大小,一个扇区DW1; FAT的起始位置,一般冲第一个扇区开始DB2; FAT的个数,必须为2DW224; 根目录的大小,一般设置成224项DW2880; 该磁盘的大小,一般设置为2880扇区DB0xf0; 磁盘的种类DW9; FAT的长度,此处是九扇区DW18; 一个磁道的扇区数目DW2; 磁头数目DD0; 不使用分区,此处是0DD2880; 重写一次磁盘大小DB0,0,0x29; 未知意义DD0xffffffff; 可能为卷标号码DB"HARIBOTEOS "; 磁盘的名称, 11个字节DB"FAT12   "; 磁盘个数名称RESB18; 先空出18个字节; 程序主体entry:MOVAX,0; 初始化寄存器MOVSS,AXMOVSP,0x7c00MOVDS,AX; 读入扇区MOVAX,0x0820;读入的程序存储的内存区域,通过计算得到,为伪代码MOVES,AXMOVCH,0; 柱面0MOVDH,0; 磁头0MOVCL,2; 扇区2readloop:MOVSI,0; 记录失败次数的寄存器,最多重试五次retry:MOVAH,0x02; AH=0x02 : 读盘MOVAL,1; 一个扇区MOVBX,0MOVDL,0x00; A驱动器INT0x13; 调用磁盘BIOS,磁盘读写JNCnext; ADDSI,1; 往SI加一CMPSI,5; 比较JAEerror; SI >= 5 ,跳至错位处理程序MOVAH,0x00MOVDL,0x00; A驱动器INT0x13; 重置驱动器JMPretrynext:MOVAX,ES; 把内存地址后移0x200,表示为十进制为512个字节,即一个扇区的大小ADDAX,0x0020MOVES,AX; ADD ES,0x020 这个指令没法实现,所以通过AX来中转ADDCL,1; CL加1CMPCL,18; 比较CL与18,一个柱面得到18个扇区读完后读下一个柱面的第一个扇区JBEreadloop; CL <= 18 ,则跳转至readloopMOVCL,1ADDDH,1CMPDH,2JBreadloop; DH < 2 ,跳转到readloopMOVDH,0ADDCH,1CMPCH,CYLSJBreadloop; CH < CYLS 跳转到readloop; 跳转到haribote.sys的准备工作MOV[0x0ff0],CH; IPL在哪里读到的记录,CH为10(读入的柱面数目)JMP0xc200          ;操作系统载入到的内存地址(开始载入位置+ 内容相对位置)error:MOVSI,msgputloop:MOVAL,[SI]ADDSI,1; SI加上1CMPAL,0JEfinMOVAH,0x0e; 显示一个文字MOVBX,15; 指定字符颜色INT0x10; 调用显卡BIOS功能JMPputloopfin:HLT; CPU停止等待指令JMPfin; 死循环msg:DB0x0a, 0x0a; 换行两次DB"load error"DB0x0a; 执行DB0RESB0x7dfe-$; 0x7dfe地址以前填充0x00DB0x55, 0xaa      ;扇区最后两个字节,表面该扇区存储的是启动程序