【0】写在前面

要知道,在汇编中,代码的装入顺序决定了在内存中的地址位置。所有的代码或者数据都在硬盘上,当调试或者启动的时候,加载到内存;当需要对数据进行处理的时候,我们通过将数据从内存载入到registers 通过cpu来进行处理的。



【1】初始化各种段描述符

以 初始化 32 位代码段描述符 为例

【2】有感

首先:要先定义这段描述符(占据内存空间),然后向里面传入真正处理数据的地址;

2.1 定义阶段

为什么 LABEL_GDT 必须跟在最前面呢?

  • 因为它的地址要作为段的基地址,而选择子的地址作为偏移地址来定位某个段。你想想你C语言的数组,是不是这样排列的。首先数组首地址在开头,然后后面存储的是元素的地址,呵呵。碉堡了。一句话说完;

    只要吧LABEL_GDT放在某段内存的起始位置,跟在它后面的哪些段描述符(内存地址),都可以作为GDT中的元素(或者称为表项),这就是一个表(或者数组)的定义由来。

    LABEL_GDT:         Descriptor       0,                 0, 0         ; 空描述符

    LABEL_DESC_CODE32: Descriptor 0, SegCode32Len - 1, DA_C + DA_32 ; 非一致代码段, 32

2.2 定义选择子

说白了,选择子就是某个段相对于全局描述符GDT的偏移地址; 当我们知道GDT的地址后,将其作为基地址,并将选择子作为偏移地址,来定位该段描述符的。

; GDT 选择子
SelectorCode32 equ LABEL_DESC_CODE32 - LABEL_GDT

2.3 往段描述符空间装干货地址

干货就是真正的处理数据的代码。(如向屏幕显示打印字符)

[SECTION .s16]
[BITS 16]
LABEL_BEGIN:
;start point: jmp会跳到这里
mov ax,trong
mov ax,GdtLen
mov ax, cs
mov ds, ax
mov es, ax
mov ss, ax
mov sp, 0100h ; 初始化 32 位代码段描述符(装干货地址)
xor ax, ax
mov ax, cs
shl ax, 4
add ax, LABEL_SEG_CODE32
mov word [LABEL_DESC_CODE32 + 2], ax
shr ax, 16
mov byte [LABEL_DESC_CODE32 + 4], al
mov byte [LABEL_DESC_CODE32 + 7], ah ; 为加载 GDTR 作准备(将全局描述符表GDT装入全局描述符表寄存器GDTR,目的是跳转的时候,程序要到GDTR取段基地址)
xor ax, ax
mov ax, ds
shl ax, 4
add ax, LABEL_GDT ; eax <- gdt 基地址
mov dword [GdtPtr + 2], eax ; [GdtPtr + 2] <- gdt 基地址 ; 加载 GDTR (正式加载到全局描述符表寄存器)
lgdt [GdtPtr] ; 关中断
cli ; 打开地址线A20
in al, 92h
or al, 00000010b
out 92h, al ; 准备切换到保护模式
mov eax, cr0
or eax, 1
mov cr0, eax ; 真正进入保护模式 (这里就要查询GDTR了,跳转到干货地址)
jmp dword SelectorCode32:0 ; 执行这一句会把 SelectorCode32 装入 cs,
; 并跳转到 Code32Selector:0 处
; END of [SECTION .s16]

2.4 真正的干货

[SECTION .s32]; 32 位代码段. 由实模式跳入.
[BITS 32]
LABEL_SEG_CODE32:
mov ax, SelectorData
mov ds, ax ; 数据段选择子
mov ax, SelectorVideo
mov gs, ax ; 视频段选择子
mov ax, SelectorStack
mov ss, ax ; 堆栈段选择子
mov esp, TopOfStack
。。。。。。

【3】GDT + LDT (全局描述符表+局部描述符表) from p49.asm

3.1 GDT的首地址(基地址)定义, 跟在它后面的都是其表项

3.1.1 GDT定义

[SECTION .gdt]
; GDT
; 段基址, 段界限 , 属性
LABEL_GDT: Descriptor 0, 0, 0 ; 空描述符
LABEL_DESC_NORMAL: Descriptor 0, 0ffffh, DA_DRW ; Normal 描述符
LABEL_DESC_CODE32: Descriptor 0, SegCode32Len - 1, DA_C + DA_32 ; 非一致代码段, 32
LABEL_DESC_CODE16: Descriptor 0, 0ffffh, DA_C ; 非一致代码段, 16
LABEL_DESC_DATA: Descriptor 0, DataLen - 1, DA_DRW+DA_DPL1 ; Data
LABEL_DESC_STACK: Descriptor 0, TopOfStack, DA_DRWA + DA_32; Stack, 32 位
LABEL_DESC_LDT: Descriptor 0, LDTLen - 1, DA_LDT ; LDT (局部描述符表)
LABEL_DESC_VIDEO: Descriptor 0B8000h, 0ffffh, DA_DRW ; 显存首地址
; GDT 结束

3.1.2 LDT定义

; LDT
[SECTION .ldt]
ALIGN 32
LABEL_LDT:
; 段基址 段界限 属性
LABEL_LDT_DESC_CODEA: Descriptor 0, CodeALen - 1, DA_C + DA_32 ; Code, 32 位
LDTLen equ $ - LABEL_LDT
; LDT 选择子
SelectorLDTCodeA equ LABEL_LDT_DESC_CODEA - LABEL_LDT + SA_TIL
; END of [SECTION .ldt]
; CodeA (LDT, 32 位代码段)

3.2 初始化

   ; 初始化 LDT 在 GDT 中的描述符
xor eax, eax
mov ax, ds
shl eax, 4
add eax, LABEL_LDT
mov word [LABEL_DESC_LDT + 2], ax
shr eax, 16
mov byte [LABEL_DESC_LDT + 4], al
mov byte [LABEL_DESC_LDT + 7], ah
; 初始化 LDT 中的描述符
xor eax, eax
mov ax, ds
shl eax, 4
add eax, LABEL_CODE_A
mov word [LABEL_LDT_DESC_CODEA + 2], ax
shr eax, 16
mov byte [LABEL_LDT_DESC_CODEA + 4], al
mov byte [LABEL_LDT_DESC_CODEA + 7], ah
; 为加载 GDTR 作准备
xor eax, eax
mov ax, ds
shl eax, 4
add eax, LABEL_GDT ; eax <- gdt 基地址
mov dword [GdtPtr + 2], eax ; [GdtPtr + 2] <- gdt 基地址

版权声明:本文为博主原创文章,未经博主允许不得转载。

段描述符表(GDT+LDT)的有感的更多相关文章

  1. 操作系统篇-分段机制与GDT|LDT

    || 版权声明:本文为博主原创文章,未经博主允许不得转载. 一.前言     在<操作系统篇-浅谈实模式与保护模式>中提到了两种模式,我们说在操作系统中,其实大部分时间是待在保护模式中的. ...

  2. GDT,LDT,GDTR,LDTR 详解,包你理解透彻(转)

    引自:http://www.techbulo.com/708.html 一.引入 保护模式下的段寄存器 由 16位的选择器 与 64位的段描述符寄存器 构成 段描述符寄存器: 存储段描述符 选择器:存 ...

  3. EPROCESS 进程/线程优先级 句柄表 GDT LDT 页表 《寒江独钓》内核学习笔记(2)

    在学习笔记(1)中,我们学习了IRP的数据结构的相关知识,接下来我们继续来学习内核中很重要的另一批数据结构: EPROCESS/KPROCESS/PEB.把它们放到一起是因为这三个数据结构及其外延和w ...

  4. 【转】操作系统 gdt ldt

    GDT的由来:     在Protected Mode下,一个重要的必不可少的数据结构就是GDT(Global Descriptor Table). 为什么要有GDT?我们首先考虑一下在Real Mo ...

  5. linux内核学习之全局描述符表(GDT)(二)

    来源:https://www.cnblogs.com/longintchar/p/5224406.html 在进入保护模式之前,我们先要学习一些基础知识.今天我们看一下全局描述符表(Global De ...

  6. 全局描述符表GDT

    写在前面 添油加醋系列第二弹--剖析GDT 头文件:https://github.com/bajdcc/MiniOS/blob/master/include/gdt.h 实现:https://gith ...

  7. GDT,LDT,GDTR,LDTR (转 侵删)

    一.引入 保护模式下的段寄存器 由 16位的选择器 与 64位的段描述符寄存器 构成 段描述符寄存器: 存储段描述符 选择器:存储段描述符的索引 段寄存器(16位选择子,64为隐藏信息) 原先实模式下 ...

  8. Bran的内核开发教程(bkerndev)-06 全局描述符表(GDT)

    全局描述符表(GDT)   在386平台各种保护措施中最重要的就是全局描述符表(GDT).GDT为内存的某些部分定义了基本的访问权限.我们可以使用GDT中的一个索引来生成段冲突异常, 让内核终止执行异 ...

  9. 获取全局描述符表GDT的内容

    /stdfx.h文件 //Ring0环的程序 //测试环境VS2005 #ifndef _WIN32_WINNT // Allow use of features specific to Window ...

随机推荐

  1. HNC-全局联想脉络

    全局联想脉络—语义块 和句类 一个语义块包含 核心部分 和说明部分. 语义块分为: 主语义块:有 4 种:特征E.作用者A.对象B.内容C 辅语义块:有 7 种:条件.手段.工具.途径.参照.因.果. ...

  2. 更有效率的使用Visual Studio(一)

    很多比较通用的快捷键的默认设置其实是有一些缩写在里面的,这个估计也是MS帮助我们记忆.比如说注释代码的快捷键是Ctrl + E + C,我们如果知道它是 Ctrl + Edit + Comment C ...

  3. EasyMock使用说明

    来自官网的使用说明,原文见http://www.easymock.org/EasyMock2_0_Documentation.html 1.1. 准备 大多数的软件系统都不是单独运行的,它们都需要于其 ...

  4. 笔记本键盘上没有break键的解决方案

    django在Windows上调试需要用ctrl+break终止服务器……笔记本键盘上没有break好尴尬…… 在百度搜了很多都没有找到,最后终于在谷歌上找到了英文版的解决方案. starting o ...

  5. [转]AsyncDisplayKit 教程:达到 60 FPS 的滚动帧率

    [原文:https://github.com/nixzhu/dev-blog/blob/master/2014-11-22-asyncdisplaykit-tutorial-achieving-60- ...

  6. 使用foreach碰到的问题

    foreach($list as $k=>$v ){ ........... } 和下面: foreach($list as &$v){ ........ } 其实两者的结果是一样的,但 ...

  7. nested exception is java.io.FileNotFoundException: class path resource [spring/spring-datasource-mog

    spring单元測试时发现的问题: org.springframework.beans.factory.BeanDefinitionStoreException: IOException parsin ...

  8. NGINX源代码剖析 之 CPU绑定(CPU亲和性)

    作者:邹祁峰 邮箱:Qifeng.zou.job@gmail.com 博客:http://blog.csdn.net/qifengzou 日期:2014.06.12 18:44 转载请注明来自&quo ...

  9. TP复习8

    ## ThinkPHP 3.1.2 视图#讲师:赵桐正微博:http://weibo.com/zhaotongzheng 本节课大纲:一.模板的使用 (重点) a.规则 模板文件夹下[TPL]/[分组 ...

  10. 在 linux(ubuntu) 下 安装 LibSVM

    原文:http://blog.csdn.net/rav009/article/details/12995095 在安装LibSVM前需要先装 python 和 gnuplot linux 一般都自带了 ...