下面开始我们新的一章的学习了。在这章开头,我先要吐槽一下这本书,我觉得这本在第三章,也就是第三天这里,感觉有些地方作者
讲的很含糊,有的地方需要深入的讲解却没有,但是有很多所谓的“风趣”的话,但是我倒不觉得有多风趣,纯属吐槽。
好了下面开始进入正文,在进入正文之前先讲解几个重要的概念
启动区:(boot sector)软盘第一个的扇区成为启动区,就是0面0道1扇区。那么什么是扇区呢?计算机读写软盘的时候,并不是一个字节
一个字节地读写的,而是以512字节为一个单位进行读写。因此软盘的512个字节就称为一个扇区,一张软盘的空间共有1440KB,也就是
1474560字节,除以512得2880,这也就是说一张软盘共有2880个扇区。那为什么第一个扇区称为启动区呢?那是因为计算机首先从最初一个
扇区开始读软盘,然后去检查这个扇区最后2个字节的内容。如果这最后2个字节不是55AA,计算机会认为这张软盘上没有所需的启动程序,就
会报一个不能启动的错误。如果计算机确认第一个扇区的最后两个字节正好是55AA,那它就认为这个扇区的开头是启动程序,并开始执行这个程序。
IPL:(initial program loader)的缩写。启动程序加载器,启动区只有区区512字节,实际的操作系统很大,根本装不进去,所以几乎所有
的操作系统,都是把加载操作系统本身的程序放在启动区里的。有鉴于此,有时也将启动区称为IPL。
概念说完,那就上代码了:
; haribote-ipl ; TAB=4 CYLS EQU 10 ORG 0x7c00 JMP entry DB 0x90 DB "HARIBOTE" DW 512 DB 1 DW 1 DB 2 DW 224 DW 2880 DB 0xf0 DW 9 DW 18 DW 2 DD 0 DD 2880 DB 0,0,0x29 DD 0xffffffff DB "HARIBOTEOS " DB "FAT12 " RESB 18 entry: MOV AX,0 MOV SS,AX MOV SP,0x7c00 MOV DS,AX MOV AX,0x0820 ;表示要把磁盘0柱面0磁头2扇区的数据加载到内存0x8200开始的位置 MOV ES,AX MOV CH,0 ;柱面0 MOV DH,0 ;磁头0 MOV CL,2 ;扇区2 readloop: MOV SI,0 retry: ;这里是读一个扇区的操作 MOV AH,0x02 ;AH=0x20:读盘 MOV AL,1 ;1个扇区(表示要处理的扇区数) MOV BX,0 MOV DL,0x00 ;A驱动器 INT 0x13 ;调用磁盘BIOS JNC next ;读盘没出错那就跳转到next标号 ;这里是试错操作,软盘这东西很不可靠,有时发生不能读数据的状况,这时候重新再读一次就行了。 ADD SI,1 CMP SI,5 JAE error MOV AH,0x00 MOV DL,0x00 INT 0x13 JMP retry next: ;移动地址 MOV AX,ES ;把内存地址后移0x200(为什么?下面讲解) ADD AX,0x0020 MOV ES,AX ;下面的操作就是从C0-H0-S1一直读到C9-H1-S18 ADD CL,1 CMP CL,18 JBE readloop ;循环18个扇区 MOV CL,1 ADD DH,1 CMP DH,2 JB readloop ;循环磁头 MOV DH,0 ADD CH,1 CMP CH,CYLS JB readloop ;循环柱面 MOV [0x0ff0],CH ;保存CYLS值 JMP 0xc200 ;跳转到0xc200地址开始执行指令 ;下面这串暂时没用,可以忽略 error: MOV SI,msg putloop: MOV AL,[SI] ADD SI,1 CMP AL,0 JE fin MOV AH,0x0e MOV BX,15 INT 0x10 JMP putloop fin: HLT JMP fin msg: DB 0x0a, 0x0a DB "load error" DB 0x0a DB 0 RESB 0x7dfe-$ DB 0x55, 0xaa
1,下面先来看看几个BIOS的函数调用
INT 0x13:磁盘读,写,扇区校验,以及寻道
AH = 0x02;(读盘)
AH = 0x03;(写盘)
AH = 0x04;(校验)
AH = 0x0c;(寻道)
AL = 处理对象的扇区数(只能同时处理连续的扇区)
CH = 柱面号 & 0xff;
CL = 扇区号(0-5位) | (柱面号&0x300) >> 2;
DH = 磁头号;
DL = 驱动器号
ES:BX=缓冲地址;(校验及寻道时不使用)
返回值: FLACS.CF == 0: 没有错误,AH==0
FLAGS.CF == 1: 有错误,错误号码存入AH内
INT 0x13
AH = 0x00
DL = 0x00
这个三个组合就是系统复位功能,它的功能是复位软盘状态,再读一次。
2,下面要总结几个跳转指令
(1),JC,是"jump if carry"的缩写,意思是如果进位(carry flag)是1的话,就跳转。
(2),JNC,是"jump if not carry"的缩写,意思是如果进位(carry flag)是0的话,就跳转。
(3),JAE,是"jump if above or equal"的缩写,意思是大于或等于时跳转。
(4),JB,是"jump if below"的缩写,如果小于的话,就跳转
3,讲解几个我觉得需要注意的地方
(1)就是程序开始时为什么要将ES指定为0x0820?作者的理由如下:
我们指定了ES=0x0820,BX=0,所以软盘的数据将被装载到内存中0x8200到0x83ff的地方,可能有人会想,怎么也不弄个整点的数,
比如0x8000什么的,那多好,但0x8000-0x81ff这512字节是留给启动区的,要将启动区的内容读到那里,所以就这样吧。
但在后面作者又说0x7c00-0x7dff用于启动区,0x7e00以后直到0x9fbff为止的区域没有特别的用途,操作系统可以随便使用。
所以这里就给我造成了疑问,但是是0x8000-0x81ff还是0x7c00-0x7dff用于启动区呢,BIOS规定为把0盘0面1扇区的内容加载到
0x7c00的位置,这肯定是无可厚非的。但是作者后面又说0x8000-0x81ff这512字节是留给启动区的呢?
但是,我觉得一定不是作者弄错了,只不过没表达清晰而已,因为我们的代码是从0盘0面2扇区的内容开始加载进来的,假如我们
的代码是从0盘0面1扇区的内容加载的,那么物理地址=0x8200+汇编地址(即是当前的代码相对于文件的偏移量),但是问题现在
作者是从0盘0面2扇区的内容,所以作者把0x8000-0x8lff预留给启动区的(即使作者这段地址实际上是没用的),那么现在的物理地址
=0x8000+汇编地址。这里有点难解释清楚,得自己看书好好体会。
(2)第二个问题我觉的是作者的疏忽。在第52页中作者写到:"CL是扇区号,ES指定读入地址。0x20是十六制512除以16的结果,如果
写成ADD AX,512/16或许更好懂,笔者在写的时候,直接在头脑中换算成了0x20,当然写成512/16也一样。可能有人会说:往BX里加上
512不是更简单吗",这里的代码不能直接往BX直接加上512,因为每次BX的值每次都被更新为0了,除非上面的代码需要改了。
那下面可以看看这个启动区的代码怎么来进行加载下面的helloworld程序。
; haribote-os ; TAB=4 ORG0xc200 entry: MOVAX,0 MOVSS,AX MOVSP,0xc200 MOVDS,AX MOVES,AX MOVSI,msg putloop: MOVAL,[SI] ADDSI,1 CMPAL,0 JEfin MOVAH,0x0e MOVBX,15 INT0x10 JMPputloop fin: HLT JMPfin msg: DB0x0a, 0x0a DB"hello, world" DB0x0a DB0
运行效果如下:
相关推荐
装载器是在程序实际运行时启动的,它的主要职责是将可执行文件加载到内存中并准备执行。这包括解析可执行文件的格式,分配内存空间,将代码和数据复制到内存,以及设置程序计数器和其他必要的寄存器。装载器还需要...
1. **Bootstrap ClassLoader**(启动类装载器):这是JVM自带的类装载器,用于加载核心类库(如`java.lang.*`)。它没有父类装载器。 2. **Extension ClassLoader**(扩展类装载器):它通常用来加载`JAVA_HOME/lib/...
### WinCE下冷启动程序自动安装装载 在深入探讨如何实现Windows CE(简称WinCE)下的冷启动程序自动安装装载之前,我们先来了解一下WinCE系统的一些基本概念以及为何需要进行冷启动程序的自动安装。 #### Windows ...
文件内容可能包括源代码、实验报告、程序解释以及可能的测试案例等,这些都能帮助我们更好地理解这个自启动程序的设计和功能。 综上所述,这个项目涵盖了汇编语言编程、操作系统原理、引导加载器的实现以及程序管理...
引导装载程序是系统启动过程中的关键部分,它负责初始化硬件,加载操作系统内核,并将控制权传递给内核,使系统能够正常运行。 在提供的压缩包中,包含`.h`和`.c`文件,这表明它是用C语言编写的源代码。`.h`文件...
在操作系统开发中,启动程序通常非常小,仅能加载更复杂的启动代码,这些代码可能位于磁盘的其他位置。操作系统的主体部分通常由C语言和汇编语言混合编写,保存为文件后,由引导程序加载到内存。DOS和Windows下的COM...
这个模型可以用层次结构来表示,例如,系统类装载器(AppClassLoader)的父类是扩展类装载器(ExtClassLoader),扩展类装载器的父类是启动类装载器(Bootstrap ClassLoader)。在示例代码`LoaderSample1`中,我们...
在本教程中我们还发布一个用C++语言编写的框架,帮助快速编写通用的、复杂的应用程序装载器。我们并不打算发布一个框架库,因为若要编写装载器你首先得读懂附件中C或C++源码,所以就把它的编译任务做为你的家庭作业...
2. **启动类装载器(Bootstrap ClassLoader)**:它是JVM内置的最顶层类装载器,负责加载JDK核心库,如rt.jar中的类。 3. **扩展类装载器(Extension ClassLoader)**:负责加载Java扩展目录(`<JAVA_HOME>/jre/lib...
Java的类装载器分为三个基本层次:启动类装载器(Bootstrap ClassLoader)、扩展类装载器(Extension ClassLoader)和应用程序类装载器(Application ClassLoader)。它们共同协作,根据类的全限定名(包括包名和...
- **C语言环境准备**:链接器的分布装载功能用于将数据从ROM移动到RAM,同时为中断处理等高优先级任务分配运行空间。 - **调用C程序**:启动程序的最后一步,启动C程序执行,标志着应用程序的正式开始。 3. ARM7...
ARM7 在嵌入式应用中启动程序的实现 嵌入式系统是以应用为中心、以...ROM 中运行等因素,需要对系统硬件和软件运行环境进行初始化,合理安排启动程序的流程,并解决技术难点如 MMU 的使用和目标文件的分布装载等。
引导装载程序,简称Bootloader,是系统启动时运行的第一段程序,它在操作系统内核运行之前执行,主要负责初始化硬件设备,建立内存空间的映射图,以及为操作系统内核提供一个合适的运行环境。在嵌入式系统中,...
【ARM7嵌入式系统启动程序的实现与设计】 嵌入式系统是计算机技术与特定应用相结合的产物,它的核心是嵌入式处理器。ARM7作为一款32位RISC(精简指令集)芯片,广泛应用在消费电子、军事、航空航天等多个领域。ARM...
在IT领域,"装载镜像"通常指的是将操作系统或应用程序的映像文件加载到计算机的内存中,以便启动和运行。这个过程在多种场景中都非常重要,比如系统安装、故障恢复或者虚拟化环境的配置。"重装系统"则是指在计算机上...
在本文中,我们将深入探讨如何使用三菱PLC(可编程逻辑控制器)编写一个控制四台电机启动的程序。三菱PLC是工业自动化领域广泛应用的一种控制器,尤其在机械设备和生产线的控制上表现出色。通过理解其编程语言和逻辑...
### 44B0启动程序详细说明文档及ADS配置 #### 概述 本文档旨在对44B0启动程序及其ADS配置进行详尽解析,包括但不限于程序的主要功能、内部结构以及配置细节等内容。该文档适用于希望深入了解44B0启动程序内部机制...