30天自制操作系统学习笔记----day_three

、实验主要内容

1.制作真正的IPL:

关键代码如下:

  

重点内容:

  1. JC指令是“jump if carry”的缩写,常用来判断是否产生进位,如果产生进位,则标志位置为1同时跳转到指定地址,否则标志位为0。
  2. INT 0x13是调用BIOS的0x13号函数,该函数负责磁盘读写方面的工作。不同寄存器对应的功能如下:

AH = 0x02;//读盘模式

AH = 0x03;//写盘模式

AH = 0x04;//校验

AH = 0x0c;//寻道

AL = 处理对象的扇区数,意思就是当前读取的柱面的扇区数,但只能处理连续的扇区。

CH = 柱面号 & 0xff 记录当前读取的柱面号。

CL = 扇区号(0-5位)| (柱面号 & 0x300)>>2;记录当前读取的扇区号。

DH = 磁头号,记录当前磁头的编号。

DL = 驱动区号,用于指定从哪个驱动区软盘读取数据。

ES:BX = 缓冲地址,计算公式如下:ES x 16 + BX

FLACS.CF 状态寄存器,用于记录软盘读取过程中是否发生错误,出现错误则置为1,同时错误号码存入AH寄存器中,否则该状态寄存器为0。

  1. 进位标志是一个只能存储1位信息的寄存器,若产生进位则值为1,否则为0,可用于判断BIOS调用函数是否出错等等。
  2. 软盘的结构:软盘由磁头、柱面、扇区构成。其中磁头分为磁头0、磁头1,读取软盘正反面,共有80个柱面,从0开始编号到79。每个柱面包含18个扇区,扇区从1开始编号到18,其中每个扇区的大小为512个字节。读取或写入数据的流程:确定磁头号--->确定柱面号--->锁定扇区号--->读取或写入数据。
  3. 缓冲地址:表明从磁盘读取出来的数据放在内存中的位置。常用ES:BX的方式来表示地址,在内存中的位置由ES x 16 +BX计算得到,这样可以获得更大的地址空间。
  4. 段寄存器,当指定内存中的某一个地址时,都必须要指定段寄存器。一般默认将“DS:”作为段寄存器。因此MOV CX,[1234] 其实就是 MOV CX,[DX:1234]。关于段寄存器的一些扩展:

A) 代码段寄存器CS:存放当前正在运行的程序代码所在段的段基值,表示当前使用的指令代码可以从该段寄存器指定的存储器段中取得,相应的偏移值则由IP提供。
B) 数据段寄存器DS:指出当前程序使用的数据所存放段的最低地址,即存放数据段的段基值。
C) 堆栈段寄存器SS:指出当前堆栈的底部地址,即存放堆栈段的段基值。
D)附加段寄存器ES:指出当前程序使用附加数据段的段基址,该段是串操作指令中目的串所在的段。

  1. DS在使用的时候务必预先指定值为0,否则被指定的地址的值需要加上DS的16倍,否则就会读写到其它地方,如图: 

2.试错

关键代码:

     重点内容:

  1. JNC是“jump if not carry”的简写,更前面出现的JC指令相反,JNC是不产生进位的时候则跳转。
  2. 由于软盘容易出错,因此重新读盘之前都要进行复位处理。也就是上面代码开头的第一部分。

3.读入18个扇区

关键代码:

重点内容:

  1. 为什么CL从2开始读呢?因为第一个扇区已经作为启动区了。
  2. JBE指令是“jump if below or equal”的简写,意思就是小于等于则跳转。
  3. 读入下一个扇区只需要给CL加一即可,SI寄存器用于记录软盘读取出错的次数,大 于5次时调到erro处。
  4. 一个扇区数512字节,每读取一个扇区则内存地址往后面移动512/16 = 0x20个位置。

4.读入10个柱面

关键代码:

重点内容:

  1. 读取柱面比读取扇区的代码多了判断柱面数,当柱面数达到十个则停止读取,否则一直循环读取。
  2. JB指令是“jump if below”,意思是小于的时候跳转。
  3. CYLS EQU 10 是预先定义CYLS的值为10,就相当于c语言的#define声明一个常量。

5.着手开发操作系统

重点内容:

(1)当向一个软盘保存文件时:文件名会写在0x002600以后的地方,文件的内容会写在0x004200以后的地方。

6.从驱动区执行操作系统

重点内容:程序从启动区开始,把磁盘内容装载到内存的0x8000号地址,那么软盘0x4200处的内容应该位于内存0x8000+0x4200 = 0xc200号地址。

7.确认操作系统执行情况

关键代码:

重点内容:

  1. ORG指明程序被装载到内存的地址。

显卡中断函数不同的设置对应功能如下:(该函数无返回值)

AH = 0x00;//初始化

AL = 模式:

0x03 :16色字符模式,80x25;

0x12:VGA图形模式,640x480x4位彩色模式,独特的4面存储模式;

0x13:VGA图形模式,320x200x8位彩色模式,调色板模式;

0x6a:扩展VGA图形模式,800x60044位彩色模式,独特的4面存储模式。部分显卡不支持该模式。

本段代码选用的是第三种显示模式。

  1. 运行结果:make run

成功出现黑屏。

8.32位模式前期准备

关键代码:

重点内容:

  1. CPU有16位和32位两种模式,16位模式的机器语言只能在16位模式下运行,32位也是如此。
  2. 32位模式的cpu可以使用的内存容量远远大于1MB,且cpu的自我保护功能可以在32位模式下使用。
  3. 32位模式下不能调用之前的BIOS功能了,因为它基于16位模式写的。解决办法:切换系统模式。
  4. 上面的程序在设置画面模式之后,会将画面模式的信息保存在内存中,留起来备用。
  5. VRAM指的是显卡内存,它的每个地址上都存放了对应画面的每一个像素,利用这个机制可以在画面上绘制五彩缤纷的图案。
  6. VRAM分布在内存好几个不同的地方,不同的画面模式的像素数也一样。

9.开始导入c语言

关键代码:

重点内容:

  1. goto指令相当于汇编中的JMP;
  2. C语言编程机器语言的过程:

  1. cc1是C编译器,可以将C语言编译成汇编语言。
  2. gas2nask.exe将gas文件编译成nask文件;
  3. nask.exe将nask文件编译成obj目标文件;
  4. obj2bim将obj文件编译成二进制文件,同理其它。
  5. 一个完整的img文件由多个部分链接而成。

10.实现HLT

关键代码:

重点内容:

  1. 为了与bootpack.obj链接,该段代码需要编译成二进制文件,因此设置输出模式为:WCOFF模式,同时设定成32位模式。
  2. 制作nask目标文件,必须设定文件名信息,最后声明函数名,但是需要在函数名前面加上”_”,否则就不能很好地与c语言函数链接。用GLOBAL声明需要链接的函数。
  3. 最终的c语言程序如图:

二、遇到的问题及解决方法

无。(部分同学可能会出现报Windows ....255号Erro,出现这样的原因是由于最近Windows的更新引起的,解决办法重新替换实验文件就好了)

三、程序设计创新点

尝试着想让黑屏显示一点东西,黑屏的显示通过VRAM,因此向VRAM写入东西,应该就可以显示。尝试过程:首先修改写入VRAM的数据

行后发现仍然是黑屏!

后面查找到第四天有相关内容。在naskfuncs.nas加入以下内容:

原理是将原来的黑像素点变成白的。

同时c语言加入以下内容:

运行结果如图:

示其他的内容,对c语言下的:

这部分内容进行修改即可。

 

猜你喜欢

转载自blog.csdn.net/weixin_42294984/article/details/83589380