段描述符表(GDT+LDT)的有感
【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)的有感的更多相关文章
- 操作系统篇-分段机制与GDT|LDT
|| 版权声明:本文为博主原创文章,未经博主允许不得转载. 一.前言 在<操作系统篇-浅谈实模式与保护模式>中提到了两种模式,我们说在操作系统中,其实大部分时间是待在保护模式中的. ...
- GDT,LDT,GDTR,LDTR 详解,包你理解透彻(转)
引自:http://www.techbulo.com/708.html 一.引入 保护模式下的段寄存器 由 16位的选择器 与 64位的段描述符寄存器 构成 段描述符寄存器: 存储段描述符 选择器:存 ...
- EPROCESS 进程/线程优先级 句柄表 GDT LDT 页表 《寒江独钓》内核学习笔记(2)
在学习笔记(1)中,我们学习了IRP的数据结构的相关知识,接下来我们继续来学习内核中很重要的另一批数据结构: EPROCESS/KPROCESS/PEB.把它们放到一起是因为这三个数据结构及其外延和w ...
- 【转】操作系统 gdt ldt
GDT的由来: 在Protected Mode下,一个重要的必不可少的数据结构就是GDT(Global Descriptor Table). 为什么要有GDT?我们首先考虑一下在Real Mo ...
- linux内核学习之全局描述符表(GDT)(二)
来源:https://www.cnblogs.com/longintchar/p/5224406.html 在进入保护模式之前,我们先要学习一些基础知识.今天我们看一下全局描述符表(Global De ...
- 全局描述符表GDT
写在前面 添油加醋系列第二弹--剖析GDT 头文件:https://github.com/bajdcc/MiniOS/blob/master/include/gdt.h 实现:https://gith ...
- GDT,LDT,GDTR,LDTR (转 侵删)
一.引入 保护模式下的段寄存器 由 16位的选择器 与 64位的段描述符寄存器 构成 段描述符寄存器: 存储段描述符 选择器:存储段描述符的索引 段寄存器(16位选择子,64为隐藏信息) 原先实模式下 ...
- Bran的内核开发教程(bkerndev)-06 全局描述符表(GDT)
全局描述符表(GDT) 在386平台各种保护措施中最重要的就是全局描述符表(GDT).GDT为内存的某些部分定义了基本的访问权限.我们可以使用GDT中的一个索引来生成段冲突异常, 让内核终止执行异 ...
- 获取全局描述符表GDT的内容
/stdfx.h文件 //Ring0环的程序 //测试环境VS2005 #ifndef _WIN32_WINNT // Allow use of features specific to Window ...
随机推荐
- SSH下载的方法2
------------------------------下作下载方法二---------------------------------------------------String msg=n ...
- .Net项目版本号的生成
给.Net项目编译的程序集加入版本号的方式有许多种,包括: 1. 默认的方式,在每个项目的AssemblyInfo.cs文件中指定版本号: // Version information for an ...
- Slave延迟很大的优化方法总结(MySQL优化)
[http://www.cstor.cn/textdetail_9146.html] 一般而言,slave相对master延迟较大,其根本原因就是slave上的复制线程没办法真正做到并发.简单说,在m ...
- 一个可创建读取日志的管理类(可固定创建2M大小的日志文件)
这里,将日志管理基类命名为LogManagerBase(抽象类),具体的不同类型的日志可以通过继承完成.该基类可将日志以每个2M的方式存储起来,并可以读取当前正在使用的日志的所有内容. 要实现该基类, ...
- 全代码实现ios-1
第一次接触ios开发时,就决定用代码开发,而不用ib.因为被ib的各种控件的联线弄得一头雾水,而且ib和storyboard变动太快了. 开始的时候真是麻烦,因为网上关于全代码开发的例子太少了,大多数 ...
- 用DataBaseMail发图片并茂的邮件
不知道各位的老板有没有这样的要求, 一些系统中的数据需要定时发出邮件提醒, 如呆料就要到期或者一些待办的事项提醒. 当然这些用SSRS报表订阅可以实现,但有些公司没有设定相应的报表服务,又或者只是一些 ...
- 工作一直没有进步怎么办?试试PDCA法则吧!
许多人在工作或者学习的时候,总是会发现自己过了一段时间以后,全然没有不论什么进步.或者进步很之少. 而对于每个渴望让自己变得更好的人来说.是一件很令人苦恼的事情,今天我们就来谈一下工作和学习上,可实现 ...
- Codeforces Round #342 (Div. 2) C. K-special Tables 构造
C. K-special Tables 题目连接: http://www.codeforces.com/contest/625/problem/C Description People do many ...
- [CSS] Introduction to CSS Columns
Learn how to use CSS columns to quickly lay out fluid columns that are responsive, degrade gracefull ...
- mybatis 报错:Caused by: java.lang.NumberFormatException: For input string
mybatis的if标签之前总是使用是否为空,今天要用到字符串比较的时候遇到了困难,倒腾半天,才在一个论坛上找到解决方法.笔记一下,如下: 转自:https://code.google.com/p/m ...