【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. 编译安装-PHP

    一.编译配置选项2 配置帮助表:2 安装目录:2 交叉编译选项:2 特征选项:3 SAPI模块设置:3 普通参数设置:4 扩展参数:4 PEAR相关选项:9 ZEND相关选项:9 TSRM线程安全资源 ...

  2. Linux 信号

    每个进程都需要有个信号处理函数,以捕捉异常信号. 我们在写代码时,有时会有内存非法使用,这种问题一般比较难定位.但是如果有信号处理函数,就可以在捕捉到SEGV信号后打印出详细信息以定位问题. 下面写一 ...

  3. android 开源 + 一些素材网站

    ui 设计工具:http://www.sketchcn.com/ 分类汇总: https://github.com/Trinea/android-open-project 直接拿来用!最火的Andro ...

  4. preventDefault stopPropagation??

    棒棒哒~ event.preventDefault https://developer.mozilla.org/zh-CN/docs/Web/API/Event/preventDefault stop ...

  5. TL-WR703 USB不稳定/当前的总结

    http://see.sl088.com/wiki/WR703_USB%E4%B8%8D%E7%A8%B3%E5%AE%9A/%E5%BD%93%E5%89%8D%E7%9A%84%E6%80%BB% ...

  6. WEB前端性能优化小结

    转:http://www.gafish.net/archives/1514 对前端开发工程师来说,前端性能优化的重要性是不言而喻的,最为大家所知的是YSLOW的23条优化规则,在我的理解中,性能优化不 ...

  7. cocos2d jsb 打包 Android APK

    1.首先要会普通的cpp 打包成Android APK 下面所说的是在cocos2d-x 2.2.2 或者 2.3 版本号中.本文在Eclipse总用ndk编译cocos2d-x. 老生常谈cocos ...

  8. 给eclipse装一些插件

    最近换了一个环境,需要折腾一个新的eclipse配置,所以在这里记录下. 1.安装marketplace help=>install,输入地址:http://download.eclipse.o ...

  9. Android 获取控件相对于屏幕位置

    // View宽,高 public int[] getLocation(View v) { int[] loc = new int[4]; int[] location = new int[2]; v ...

  10. .NET正则基础——.NET正则类及方法应用

    1        概述 初学正则时,对于Regex类不熟悉,遇到问题不知道该用哪种方法解决,本文结合一些正则应用的典型应用场景,介绍一下Regex类的基本应用.这里重点进行.NET类的介绍,对于正则的 ...