• 30天自制操作系统笔记(第六天)


    首先要讲讲GDT和IDT,前者是全局段号记录表,后者是中断记录表。

    在操作系统,中断和分段是非常重要的东西,值得一提的是,计算机在未装系统之前,内存中最靠前那一段是中断记录表,但是这个机器本身带来的中断记录表功能比较少,因此操作系统会将其删除,并新建中断向量表。分段,实际上是操作系统管理内存的一种需求,因为操作系统往往需要将很多进程载入到内存中,用分段的方法,将进程的装载地址记录下来,就能在切换进程的时候快速找到其位置,然后执行,进程管理自然也是依赖于此。

    那么,如何设置GDT和IDT呢?

    GDT的设置,有两步,第一步是将目标内存区域内容清0,这个好办,第二步是将指定段上限和地址值赋值给名为GDTR的48位寄存器。四十八位,也就是6个字节,先用汇编写出装载GDT的函数

    _load_gdtr:  ;void load_gdtr(int limit,int addr)
        MOV AX,[ESP+4]
        MOV [ESP+6],AX
        LGDT [ESP+6]
        RET

    这个汇编函数咋一看怪怪的,实际上只是对输入内容进行一个位数的调整,两个int均占四个字节,一共八个字节,有两个字节是不需要的,limit中的高位实际上是0,因为段地址是两个字节的,所以,这里的操作是把段地址这两个字节移到[ESP+6][ESP+7]上,这样,和后面的四个字节就能拼成六个字节。汇编这东西,果然繁琐!

    举个例子吧,如果传入的参数分别为limit=0xffff,addr=0x00270000,由于低位存放在内存地址更小的字节里,内存里的顺序:

                                    ff ff 00 00 00 00 27 00;

    经过GDT函数调用后,变成:

                                    00 00 ff ff 00 00 27 00;

    当然实际上可以在传参的时候就把参数倒着写,不过这就更容易写错了,自然是输入正常顺序的数进去比较合理。这里LGDT的意思自然是把这个地址后面的六个字节传入寄存器,这就设置完成了。

    中断记录表的设置和全局段号记录表类似,这里就不细说。

    鼠标的移动会触发中断,通过编写对应的中断函数可以实现鼠标在屏幕上的实时显示,而要实现这整个过程,要做两步,首先编写中断函数,然后将这个函数注册到IDT中去。

  • 相关阅读:
    20200601:百万级int数据量的一个array求和。
    20200602:千万级数据量的list找一个数据。
    20200531:假如Redis里面有1亿个key,其中有10w个key是以某个固定的已知的前缀开头的,如何将它们全部找出来?
    20200530:主从数据库不一致如何解决?
    [USACO06DEC]Milk Patterns G
    [HAOI2016]找相同字符
    [AHOI2013]差异
    [SCOI2012]喵星球上的点名
    [APIO2014]回文串
    [TJOI2015]弦论
  • 原文地址:https://www.cnblogs.com/puffmoff/p/8574474.html
Copyright © 2020-2023  润新知