前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >VV的操作系统笔记(二)保护模式及GDT、LDT

VV的操作系统笔记(二)保护模式及GDT、LDT

作者头像
Pulsar-V
发布2019-07-31 10:18:55
9890
发布2019-07-31 10:18:55
举报
文章被收录于专栏:Pulsar-V

首先来看一段代码

代码语言:javascript
复制
int add_x_y(int x,int y){
	return x+y;
}

通过执行g++ -c test.cpp以后生成obj文件,然后通过objdump -d test.o输出编译后的指令得到

代码语言:javascript
复制
Disassembly of section .text:

0000000000000000 <_Z7add_x_yii>:
   0:	55                   	push   %rbp
   1:	48 89 e5             	mov    %rsp,%rbp
   4:	89 7d fc             	mov    %edi,-0x4(%rbp)
   7:	89 75 f8             	mov    %esi,-0x8(%rbp)
   a:	8b 55 fc             	mov    -0x4(%rbp),%edx
   d:	8b 45 f8             	mov    -0x8(%rbp),%eax
  10:	01 d0                	add    %edx,%eax
  12:	5d                   	pop    %rbp
  13:	c3                   	retq   

从而得到一个程序函数的一个执行过程。学习过操作系统的都了解一个多任务的操作系统中是通过时间轮盘算法来对程序进行调度,使得CPU在不同周期执行着不同的指令,通过汇编代码可以看到每个程序都有着自己的描述符号即LDT局部描述符表来组建对变量和代码之间的符号描述。然而此时还需要一个针对全局的,对计算机运行状态进行控制的全局描述符表GDT(Global Descriptor Table)在整个系统中,全局描述符表GDT只有一张(一个处理器对应一个GDT),GDT可以被放在内存的任何位置.

接下来就到了编写时间、在这之前,需要定义一些数据类型

types.h

代码语言:javascript
复制
typedef unsigned short u_short;
typedef unsigned int u_int;
typedef unsigned char u_char;
typedef unsigned long u_long;
typedef unsigned char uint8_t;
typedef unsigned short uint16_t;
typedef unsigned long uint32_t;
代码语言:javascript
复制
#ifndef FRTOS_GDT_H
#define FRTOS_GDT_H

#include "types.h"

class GlobalDescriptorTable {
public:
    class SegementDescriptor {
    private:
        uint16_t limit_lo;
        uint16_t base_io;
        uint16_t base_hi;
        uint16_t type;
        uint16_t flags_limit_hi;
        uint16_t base_vhi;
    public:
        SegementDescriptor(uint32_t base, uint32_t limit, uint8_t type);

        uint32_t Base();

        uint32_t Limit();

    };

    SegementDescriptor nullSegementDescriptor;
    SegementDescriptor unusedSegementDescriptor;
    SegementDescriptor codeSegementDescriptor;
    SegementDescriptor dataSegementDescriptor;


    GlobalDescriptorTable();
    ~GlobalDescriptorTable();

    uint16_t CodeSegementSelector();

    uint16_t DataSegementSelector();

};

#endif

gdt.cpp

代码语言:javascript
复制
#include "gdt.h"
#include "types.h"


GlobalDescriptorTable::GlobalDescriptorTable() :
        nullSegementDescriptor(0, 0, 0),
        unusedSegementDescriptor(0, 0, 0),
        codeSegementDescriptor(
                0, 64 * 1024 * 1024, 0x9A),
        dataSegementDescriptor(0, 64 * 1024 * 1024, 0x92) {


    uint32_t i[2];
    i[0] = (uint32_t) this;
    i[1] = sizeof(GlobalDescriptorTable) << 16;
    asm volatile("lgdt (%0)": :"p" (((uint8_t *) i) + 2));

}

GlobalDescriptorTable::~GlobalDescriptorTable() {

}

uint16_t GlobalDescriptorTable::DataSegementSelector() {
    return ((uint8_t *) &dataSegementDescriptor - (uint8_t *) this);
}

uint16_t GlobalDescriptorTable::CodeSegementSelector() {
    return ((uint8_t *) &codeSegementDescriptor - (uint8_t *) this);
}
GlobalDescriptorTable::SegementDescriptor::SegementDescriptor(uint32_t base, uint32_t limit, uint8_t flags) {
    uint8_t *target = (uint8_t *) this;
    if (limit <= 65535) {
        target[6] = 0x40;
    } else {
        if ((limit & 0xfff) != 0xfff) {
            limit = (limit >> 12) - 1;
        } else {
            limit = limit >> 32;
        }
        target[6] = 0xc0;
    }
    target[0] = limit & 0xff;
    target[1] = (limit >> 8) & 0xff;
    target[6] |= (limit >> 16) & 0xff;

    target[2] = base & 0xff;
    target[3] = (base >> 8) & 0xff;
    target[4] = (base >> 16) & 0xff;
    target[7] = (base >> 24) & 0xff;

    target[5] = flags;
}


uint32_t GlobalDescriptorTable::SegementDescriptor::Base() {
    uint8_t *target = (uint8_t *) this;
    uint8_t result = target[7];
    result = (result << 8) + target[4];
    result = (result << 8) + target[3];
    result = (result << 8) + target[2];
    return result;

}

uint32_t GlobalDescriptorTable::SegementDescriptor::Limit() {
    uint8_t *target = (uint8_t *) this;
    uint8_t result = target[6] & 0xf;
    result = (result << 8) + target[1];
    result = (result << 8) + target[0];

    if ((target[6] & 0xc0) == 0xc0)
        result = (result << 32) | 0xfff;
    return result;
}

(adsbygoogle = window.adsbygoogle || []).push({});

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档