30天自制操作系统-第3天-harib00b-注释

来源:互联网 发布:网络进度计划软件 编辑:程序博客网 时间:2024/05/22 22:35

程序中的行55的执行的3种情况:
A是如果读取磁盘顺利,第一次就读取成功,那么就会进入fin语句块,如果PC机有动作唤醒了CPU,那么就继续往下执行,由于error是跳转语句块,所以这里不会执行error语句块(如果没有跳转error的指令就不会执行error语句块),所以此时SI仍然等于0,那么就进入putloop语句块,由于SI不等于msg,[SI]的值应该是0,所以AL等于0,那么就会跳回到fin语句块,也就不会在显示屏上显示内容(msg语句块对应的内容),如果PC机有动作唤醒了CPU,那么就继续往下执行(语句84~86),结束启动程序。
B是如果读取磁盘出错,但是在5次以内读取磁盘成功,那么SI就等于(1~5)中的一个值,然后就会进入fin语句块,如果PC机有动作唤醒了CPU,那么就继续往下执行,由于error是跳转语句块,所以这里不会执行error语句块,所以此时SI仍然等于(1~5)中的一个值,那么就进入putloop语句块,由于SI不等于msg,[SI]的值应该是0,所以AL等于0,那么就会跳回到fin语句块,也就不会在显示屏上显示内容(msg语句块对应的内容),如果PC机有动作唤醒了CPU,那么就继续往下执行(语句84~86),结束启动程序。
C是如果读取磁盘5次后仍然出错,那么就会进入error语句块,在error语句块中把msg的值赋给SI,由于只有JMP指令在执行跳转语句块之后还会回到原来的JMP指令的语句处继续往下执行,现在的JAE指令跳转到error语句块之后就不会再跳回JAE指令的语句处,而是在error语句块的下面继续执行,那么此时就会进入putloop语句块,由于SI等于msg,所以putloop语句块就会经过多次循环在显示屏上显示内容(msg语句块对应的内容),显示完内容之后就会跳转到fin语句块,如果PC机有动作唤醒了CPU,那么就继续往下执行(语句84~86),结束启动程序。


注意:跳转指令中,只有JMP指令在执行完跳转语句块之后还会回到原来的JMP指令的语句处继续往下执行,其它的跳转指令(比如JNC指令、JAE指令)跳转到指定的语句块之后就不会再跳回该跳转指令的语句处,而是指定的语句块的下面继续执行。


下面是程序及其注释:


; haribote-ipl; TAB=4ORG0x7c00; 指明程序的装载地址; 以下这段是标准FAT12格式软盘专用的代码JMPentry; 启动IPLDB0x90; 启动IPL之后,就可以设置下面的属性DB"HARIBOTE"; 启动区的名称可以是任意的字符串(8字)DW512; 每个扇区(sector)的大小(必须为512字节)DB1; 簇(cluster)的大小(必须为1个扇区)DW1; FAT的起始位置(一般从第一个扇区开始)DB2; FAT的个数(必须为2)DW224; 根目录的大小(一般设成224项)DW2880; 该磁盘的大小(必须是2880扇区)DB0xf0; 磁盘的种类(必须是0xf0)DW9; FAT的长度(必须是9扇区)DW18; 1个磁道(track)有几个扇区(必须是18)DW2; 磁头数(必须是2)DD0; 不使用分区,必须是0DD2880; 重写一次磁盘大小DB0,0,0x29; 意义不明,固定DD0xffffffff; (可能是)卷标号码DB"HARIBOTEOS "; 磁盘的名称(11字节)DB"FAT12   "; 磁盘格式名称(8字节)RESB18; 先空出18字节; 程序核心entry:; 初始化一些寄存器MOVAX,0; 初始化寄存器; 让累加寄存器AX的初始值为0MOVSS,AX; 让栈段寄存器SS的初始值为0MOVSP,0x7c00; 让栈指针寄存器SP的初始值为0x7c00; 见上面的ORG,程序的起始地址就是0x7c00MOVDS,AX; 让数据段寄存器DS的初始值为0; 阅读磁盘MOVAX,0x0820; 让累加寄存器AX的值为0x0820; 该语句的作用:软盘数据加载到内存中的位置0x0820~0x83ffMOVES,AX; 附加段寄存器ES的值赋值为AX的值,即0x0820; 该语句的作用:指定内存地址,先用ES指定大致的地址,下面再用BX指定其中的具体的地址,具体的内存地址是ES*16+BXMOVCH,0; 柱面0; CH计数寄存器高位为0; 指定软盘上数据加载的位置MOVDH,0; 磁头0; DH数据寄存器高位为0MOVCL,2; 扇区2; CL计数寄存器低位为2MOVSI,0; 记录失败次数的寄存器;SI是源变址寄存器retry:MOVAH,0x02; AH=0x02 ; AH累加寄存器高位的值为0x02; 该语句的作用:读盘MOVAL,1; 1个扇区; AL累加寄存器低位的值为1MOVBX,0; BX基址寄存器的值为0; 指定内存地址,具体的地址,具体的内存地址是ES*16+BXMOVDL,0x00; A驱动器; DL数据寄存器低位的值为0x00; 该语句的作用:DL用来指定驱动器号INT0x13; 调用磁盘BIOSJNCfin; 没出错的话(进位标志为0)跳转到fin,出错的话(进位标志为1),继续往下执行ADDSI,1; 往SI加1CMPSI,5; 比较SI与5JAEerror; 当SI>=5时,跳转到errorMOVAH,0x00; 复位软件状态MOVDL,0x00; A驱动器INT0x13; 调用磁盘BIOSJMPretry; 跳回retry重新执行; 让CPU睡眠,等待唤醒指令fin:HLT; 让CPU停止,等待指令唤醒JMPfin; 无限循环error:MOVSI,msg; 此时msg的地址是0x7c74(根据对应的汇编指令确定的这个地址),这里把这个值代入SI寄存器中;SI是源变址寄存器putloop:; 程序执行到(entry:)后,依次往下执行,执行到(JC error)处就跳到(error:)处执行,执行完(MOV SI,msg)后就继续往下执行(putloop:)MOVAL,[SI]; 把源变址寄存器SI所存储的内容放到累加寄存器低位AL里面去ADDSI,1; 给SI加1CMPAL,0; 比较AL是否等于0,如果AL等于0,说明[SI]储存的内容(即msg储存的内容,也就是地址0x7c74上存储的内容)等于0,也就是内容为空JEfin; 如果上面的条件成立就跳到fin中执行,如果不成立就继续往下执行,下面开始显示文字MOVAH,0x0e; 显示一个文字MOVBX,15; 指定字符颜色INT0x10; 调用显卡BIOSJMPputloop; 循环显示文字msg:DB0x0a, 0x0a; 2个换行DB"load error"; 要显示的文字DB0x0a; 换行DB0RESB0x7dfe-$; 填写0x00,直到0x7dfeDB0x55, 0xaa; 表示这个扇区的开头是启动程序,并开始执行这个程序


原创粉丝点击