第3天 进入32位模式并导入C语言
2019.12.30
1. 制作真正的IPL
-
IPL:Initial Program Loader,启动程序装载器
-
磁盘最初的512字节是启动区,所以需要装载下一个512字节的内容。
-
修改ipl.nas,添加的内容如下:
MOV AX,0x0820 MOV ES,AX MOV CH,0 ; 柱面0 MOV DH,0 ; 磁头0 MOV CL,2 ; 扇区2 MOV AH,0x02 ; AH=0x02 : 读盘 MOV AL,1 ; 1个扇区 MOV BX,0 MOV DL,0x00 ; A驱动器 INT 0x13 ; 调用磁盘BIOS JC error fin: HLT JMP fin error: MOV SI,msg
-
JC,是jump if carry的缩写,意思是:如果进位标志是1的话,就跳转。
-
指令汇总:
- DB指令:是data byte的缩写,也就是往文件里面直接写入1个字节的指令。DB命令的新用法:直接写字符串。
- RESB指令:是reserve byte的缩写,如果想要从现在的地址开始空出10个字节来,可以写成RESB 10,意思是我们预约了10个字节。nask不仅仅是把指定的地址空出来,它还会在空出来的地址上自动填入0x00。
- DW指令:data word的缩写,word在汇编里面表示16位,也就是2字节。
- DD指令:data double-word的缩写,double_word表示32位,也就是4字节。DW和DD是DB指令的“堂兄弟”。
- ORG指令:这个指令会告诉nask,再开始执行的时候,把这些机器语言指令装载到内存的哪个地址。如果没有它,有几个指令就不能正确地被翻译和执行。另外,有了这条指令的话,美元符
$
的含义也随之变化,它不再是输出文件的第几个字节,而是代表将要读入的内存地址。
ORG指令源自英文origin。它会告诉nask,程序要从指定的这个地址开始,也就是要把程序装载到内存中指定的地址。 - JMP指令:来源于英文jump,相当于C语言的goto语句。
- entry:这是标签的声明,用于指定JMP指令的跳转目的地等。
- MOV指令:最常用的指令。功能:赋值。虽然简单,但是要是完全理解了MOV指令,汇编语言也就理解了一大半了。
MOV AX,0
相当于AX=0
;MOV SS,AX
相当于SS=AX
。后者赋值给前者。- MOV指令的另一种理解是COPY。执行
MOV SS,AX
以后AX
的值并没有空,还是保持原来的值不变。
-
进位标志:调用某个函数以后,如果没有错,进位标志是0;如果有错,进位标志是1。
-
软盘
- 柱面。从外向内,一圈一圈环状的区域,分别称为柱面0、柱面1、……柱面79,共80个柱面。
- 磁头。正面磁头:0号磁头;反面磁头:1号磁头。
- 扇区。把圆环均分为18份,每一份称为一个扇区(sector),扇区编号从1开始。
- 一张软盘有80个柱面,2个磁头,18个扇区,且一个扇区有512字节。
- 因而,一张软盘的容量是
80 * 2 * 18 * 512 Byte
,即1440KB
- 含有IPL的启动区,位于
C0-H0-S1
(柱面0,磁头0,扇区1的缩写),下一个扇区是C0-H0-H2
。
-
我们在使用段寄存器时,以
ES:BX
这种方式来表示地址,写成MOV AL,[ES:BX]
,表示将内存地址ES*16+BX
中的东西给AL
。因而此时,我们只能使用最大0xfff * 16 + 0xffff = 1114095字节,即1MB内存。 -
根据上述代码,我们指定了
ES=0x0820,BX=0
.也就是说,软盘中的数据将被装载到内存中0x8200【ES*16+BX】到0x83ff【0x8200 + 0x200(512D)】 -
0x8000~0x81ff
的这512
个字节是留给