30天自制操作系统(第1-3天)

第一天

主要讲解了计算机的基本原理,以及简单介绍了汇编语言。汇编语言中有很多寄存器,完全记不住,待需要时建议临时查找,网上内容都很详细,最主要的就是看懂汇编程序。

第二天

2.1 该项目中的程序均是采用NotePad++编写,按照各自系统进行按照;

2.2 8位寄存器(其实就是前4个16位寄存器分出高位和地位)

AL——累加寄存器低位(accumulator low)

CL——计数寄存器低位(counter low)

DL——数据寄存器低位(data low)

BL——基址寄存器低位(base low)

AH——累加寄存器高位(accumulator high)

CH——计数寄存器高位(counter high)

DH——数据寄存器高位(data high)

BH——基址寄存器高位(base high)

2.3 16位寄存器

AX——累加寄存器(accumulator)

CX——计数寄存器(counter)

DX——数据寄存器(data)

BX——基址寄存器(base)

SP——栈指针寄存器(stack pointer)

BP——基址指针寄存器(base pointer)

SI——源变址寄存器(source index)

DI——目的变址寄存器(destination index)

2.4 16位段寄存器

ES——附加段寄存器(extra segment)

CS——代码段寄存器(code segment)

SS——栈段寄存器(stack segment)

DS——数据段寄存器(data segment)

FS——没有名称(segment part 2)

GS——没有名称(segment part 3)32位寄存器有8个,分别是EAX, ECX, EDX, EBX, ESP, EBP, ESI, EDI,各寄存器的首字符E为'Extend',是通过16位寄存器进行拓展得到的。

 2.5 32位寄存器

32位寄存器有8个,分别是EAX, ECX, EDX, EBX, ESP, EBP, ESI, EDI,各寄存器的首字符E为'Extend',是通过16位寄存器进行拓展得到的。

2.6 Makefile文件

该文件实现了将.c程序转变成机器语言的功能,笔者结合面经将上述功能可分为预编译、编译、汇编和链接。(由于各系统生成的中间文件格式不一定一样,所以在此就不写程序的后缀)

1. 预编译:打开头文件,将程序中的宏定义、内联函数等进行替换,并删除相关注释;

2. 编译:编译器将高级语言程序.c翻译成汇编语言程序;

3. 汇编:将汇编代码转变成机器可以执行的指令;

4. 链接:将不同的源文件产生的目标文件进行链接,从而形成一个可以执行的程序。

2.7 其他

1. 汇编语言中一些简单操作,如MOV是‘move’的缩写,表示赋值等等,就不一一介绍。

2. 0x00007c00~0x00007dff :启动区内容的装载地址

3. 0x000080000x000081ff:512字节是留给启动区的,无法使用

第三天 进入32位模式并导入C语言

3.1 制作真正的IPL

磁盘分为 软盘(00H~7FH) 和 硬盘(80H~0FFH),每个磁盘有2个磁头、80个柱面、18个扇区,每个扇区存储512字节,一个磁盘可存储2*80*18*512=1474560字节,即1440K。

该部分实现的功能为读取磁盘中的内容,BIOS中断表中的INT 13/AH=0x02为读磁盘函数,该中断函数有以下几个变量,需要对其进行赋值:

AL=扇区数
CH,CL=柱面号,扇区号
DH=磁头号
[ ES:BX ]=数据缓冲区地址,ES*16+BX
DL:驱动器号(0x00~0xFF)

输出值(CF:Carry Flag 进位标志):

读成功:CF=0,AH=0, AL=读取的扇区数
读失败:CF=1,AH=出错代码

由于启动区的装载地址为0x00007c00-0x00007dff,所以软盘的C0-H0-S2数据将被装载到内存地址0x00008200~0x000083ff。按照ES*16+BX的计算公式,得BX=0x0000、ES=(0x00008200>>4)=0x0820。(书中代码是将磁盘内容从C0-H0-S2装载到了0x8200,其实等价于将磁盘内容从C0-H0-S1装载到了0x8000BIOS中断表的链接为BIOS中断表(整理更新中2013-10-23)_int13h 256色-CSDN博客。

3.2 试错

有时候可能会出现首次无法读出,所以该节填加了一项功能,即如果失败5次则输出错误error。在出现无法读出数据时,需要重置磁盘,可用INT 13/AH=0x00为软盘重置函数,该函数有一个输入值为DL。

3.3 读到18扇区

由于每个扇区有512字节,且根据3.1中[ ES:BX ]的计算方式,得出下一个扇区的位置为ES+512/16=ES+0x0020,扇区号CL也得递增。当扇区CL>18时,使扇区CL置为1,并退出循环。

3.4 读入10个柱面

根据3.1的分析,每个柱面有18个扇区。当扇区CL>18时,读磁盘背面,即磁头DH置为1、扇区CL置为1。当DH>1时,使柱面CH+1、磁头DH=0。当DH>10,退出循环。

3.5 着手开发操作系统

总结:一般向一个空软盘保存文件时, 1. 文件名会写在0x002600以后的地方; 2. 文件的内容会写在0x004200以后的地方。(0x4200的偏移是相对C0-H0-S1的,逻辑上C0-H0-S1位于0x8000,因此是0x8000+0x4200 = 0xc200

3.6 从启动区执行操作系统

由于磁盘的装载地址为0x8000,所以文件的内容地址为0xc200,即该地址也是程序开始执行的位置。

3.7 确认操作系统的执行情况

使用中断函数INT 10/AH=0x00设置显示方式,AL=13表示320×200 256色图形(8位颜色可表示256色)。

3.8 32位模式前期准备

30天自制操作系统(第1-3天)_第1张图片

可以看到,程序中SCRNX=0x0ff4、SCRNY=0x0ff6,中间有两个字节的间隙,而MOV WORD [SCRNX],320 表示将320这个数值赋值到[ SCRNX ]地址处,而且该数值占2个字节。BYTE占1个字节,WORD占2个字节,DWORD占4个字节。需要注意的是,当寄存器间进行赋值时可不用指定字节类型,否则需要指定。如 MOV [ AX ],DX表示将寄存器DX中的值赋值到AX寄存器存储的地址中,不需要指定字节类型。

VRAM的地址为0xa00000xaffff64KB。使用中断函数INT 16/AH=0x02读键盘状态字节,并将返回值AL写入[ LEDS ]。

3.9 开始导入C语言

该部分的功能就是将.c程序转换成机器语言,参考2.6节部分。

3.10 实现待机HLT

将汇编程序转换成.c程序,注意要在函数名的前面加上“_”,否则就不能很好地与C语言函数链接,而且还需要全局声明。

你可能感兴趣的:(其他)