365bet亚洲版登录-bet官网365入口

365bet亚洲版登录拥有超过百间客房,bet官网365入口的文化历经几十年的传承和积淀形成的核心内容获得业界广泛的认可,365bet亚洲版登录是目前信誉最高的娱乐场所,同国内外几百家网上内容供应商建立了合作关系。

三十天自制操作系统

今天一开始也学最后学的用汇编写一个能被C语言调用的函数,函数名叫write_mem8,功能是在指定内容中写入特定的数据。这个函数有两个参数,第一个参数表示目标地址,第二个参数表示写入的数据。

这个函数最重要的功能就是往指定的内存地址中写入数据,那么用C语言可不可能也指定一个内存地址呢?其实是可以的,使用C语言中指针的概念就可以了。C语言中所谓的指针其是就是平时所谓的内存地址。比如想要往0xa0000内存地址中写入数据,可以这样:

int i;char* p;i = 0xa0000;p = i;*p = i;

这样就把变量i 中的内容写到内存0xa0000中了,而这个地址就是前面写的操作系统中的显存地址,往这个地方写入数据就相当于在屏幕上画上内容。

在进入32位之前,用BIOS中断把显卡设置成调色板模式。要写设置显卡中的调色板,只能使用汇编语言中的in和out指令。首先将屏蔽中断;将想要设定的调色板号码写入0x03c8,按RGB序顺写入0x03c9,如果还要继续写入,只需要继续写入0x03c9;如果要读出调色板状态,将调色板的号码写入0x03c7,再从0x03c9读取3次,调出的顺序是RGB,如果要读取下一个,只要继续从0x03c9中调取下一个调色板;结束之后,取消中断屏蔽。

中断屏蔽指令:

CLI(clear interrupt flag)

取消中断屏蔽指令:

STI(set interrupt flag)

根据C语言的规定,汇编中放入eax中的数据就是C语言的返回值。

在32位CPU的模式下操作系统中显示字符和在屏幕上画图的原理是一样的,字符只是一种特殊的图形。本书里把一个字符定义为8*16个像素的位图,那么一个字符就占16字节。一般为了画字符方便,而且操作系统为了支持不同字体功能,会另外单独定义一个字体文件,这个操作系统会在加载内存的时候把字体数据读入内存中。如果定义ASCII编码的256个字符,每个字符16字节,那么一共4096个字节,还可以接受。

sprintf(地址, 格式,值,值,值,....)

关于格式的详细说明:

  1. %d,单纯的十进制数
  2. %5d,5位十进制数
  3. %05d,在前面补0,强制达到时5位
  4. %x,单纯十六进制数字母用小写
  5. %X,单纯十六进制数字母用大写

在屏幕上显示鼠标,也就是在屏幕上画一个图像。本书把鼠标定义为16*16个像素的位图,每个像素是8个字节,总共256个字节。鼠标图像有三种颜色,第一是鼠标的边缘,我们定义为黑色,位图中用*表标;第二个是鼠标本身的颜色,我们定义为黑色,位图中用0表示;第三个是背景色,就是不显示颜色,用背景色补充,用.表示。

在32位CPU模式下,内存需要分段,为了表示一个段,需要三个信息:1、段的大小;2、段的起始地址;3、段的管理属性(禁止写入,禁止执行,系统专用等)。CPU用8个字节表示这些信息,但是段寄存器只有16位。表示的方法跟调色板很相似,先有一个段选择符,存放在段寄存器里,然后在内存中预先设定这8个字节的信息。16位段寄存器的低3位不能使用,能用的只有13位,所以一共能表示8192个段。每个段需要8个字节表示,那么一共需要8192*8=64KB表示,这64KB的数据就是GDT:global descriptor table,全局段号记录表。GDT存入在内存的某个地方,然后将内存的起始地址和有效设定个数存放在CPU的GDTR(global descriptor table rigister)中。

IDT就是中断记录表(interrupt descriptor table),当CPU遇到中断后,暂时停止正在处理的任务,转而执行中断程序。IDT记录了0~255的中断号码与调用函数的对应关系,设定方法与GDT很相似。而且要先设定GDT再设定IDT。设定IDT的目的是想让我们的操作系统对鼠标的移动作出反应。

用C语言写的操作系统源文件bootpack.c已经很长了,现在考虑要将源文件根据不同的功能拆分开来。分成三个部分:1、关于屏幕上画图的部分graph.c;2、关于GDTIDT设置的部分dsctbl.c;3、其他处理bootpack.c

由于源文件多了相应的Makefile里的编绎规则也就多了。Makefile有一个技巧可以将类似的生成规则

%.gas : %.c Makefile $ -o $*.gas $*.c%.nas : %.gas Makefile $(GAS2NASK $*gas $*.nas

make.exe会先寻找普通的生成规则,如果没有找到,就尝试用一般规则。

C语言中的include有<>和“”的区别,前者表示头文件在编绎器的文件夹中,后者表示头文件在源文件所在的文件夹中。

_load_gdtr ; void load_gdtr(int limit, int addr); mov ax, [esp + 4]; limit mov [esp + 6], ax lgdt [esp + 6] ret

这个函数将指定的段上限和地址赋值给GDTR这个48位寄存器,也就是6个字节。低16位存放段上限,它等于GDT的有效字节数-1,剩余的4个字节代表GDT的开始地址。上面程序把传入的参数limit低2字节移到高2字节,然后执行lgdt指令。

GDT中每一个段信息用8个字节表示,写的操作系统中用一个定义了一个结构体表示。

struct SEGMENT_DESCRIPTOR{ short limit_low, base_low; char base_mid, access_right; char limit_high, base_high; };

段的地址也叫做段基础,用32位表示,在结构体中用4个字段表示,分别是base_low, base_mid, base_high。正好一共4个字节。

段的大小也叫做段上限,结构体中用3个字节表示,分别是limit_low,limit_high。虽然段上限我们结构体里使用了3个字节,但是实际是有效的只有20位,另外4位表示段属性。limit_high的高4位表示段属性。段大小用20位表示,那么一个段最大的只有1MB。但是可以通过段属性中的一个位设置成1就可以把段上限的单位从字节转换成页,一页表示4KB。那么20位段上限就可以不示4GB。

结构体中还有一个字段access_right,表示段属性,也叫做段的访问权属性。段属性一共用12个字节表示,高4位保存在limit_high字段的高4位中,这4位又被叫做扩展访问权,这4位由GD00构成,G表示段上限字段的单位是字节还是页(0表示字节,1表示页)。D字段表示段模式,1是指32位,0是指16位。access_right简单说明如下:

  1. 00000000: 未使用的记录 段
  2. 10010010:系统专用,可读写,不可执行
  3. 10011010:系统专用,可执行,可读不可写
  4. 11110010:应用程序用,可读写,不可执行
  5. 11111010:应用程序用,可执行,可读不可写

在使用中断之前一定要先设置PIC,programmable interrupt controller。电脑的中断信用有15个,两个PIC,与CPU直接相连的称为主PIC,与主PIC相连的PIC称为从PIC。从PIC通过2号IRQ与主PIC相连。

PIC的所有寄存器都是8位的,IMR是interrupt mask register的缩写,中断屏蔽寄存器。8位分别对应8路IRQ信号,如果某一位设置为1则忽略该路信号。

ICW是initial control word的缩写,为初始化控制数据,一共有4个,编号分别为1-4。ICW1、ICW3,ICW4的设定值为固定,操作系统唯一能设置的是ICW2。ICW2表示IRQ以几号中断通知CPU。我们写的操作系统里把015号中断设置为0x200x2f号中断。

汇编指令pushad相当于

push eaxpush ecxpush edxpush ebxpush esppush ebppush esipush edi

相对应的也有popad

想让CPU处理中断,先写中断的处理程序,然后再把中断处理程序的入口地址注册IDT中,等到中断信号发生的时候,系统会自动调用中断处理程序。

本文由365bet亚洲版登录发布于计算机网络,转载请注明出处:三十天自制操作系统

您可能还会对下面的文章感兴趣: