【0】写在前面

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



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

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

【2】有感

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

2.1 定义阶段

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

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

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

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

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

2.2 定义选择子

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

  1. ; GDT 选择子
  2. SelectorCode32 equ LABEL_DESC_CODE32 - LABEL_GDT

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

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

  1. [SECTION .s16]
  2. [BITS 16]
  3. LABEL_BEGIN:
  4. start point jmp会跳到这里
  5. mov ax,trong
  6. mov ax,GdtLen
  7. mov ax, cs
  8. mov ds, ax
  9. mov es, ax
  10. mov ss, ax
  11. mov sp, 0100h
  12. ; 初始化 32 位代码段描述符(装干货地址)
  13. xor ax, ax
  14. mov ax, cs
  15. shl ax, 4
  16. add ax, LABEL_SEG_CODE32
  17. mov word [LABEL_DESC_CODE32 + 2], ax
  18. shr ax, 16
  19. mov byte [LABEL_DESC_CODE32 + 4], al
  20. mov byte [LABEL_DESC_CODE32 + 7], ah
  21. ; 为加载 GDTR 作准备(将全局描述符表GDT装入全局描述符表寄存器GDTR,目的是跳转的时候,程序要到GDTR取段基地址)
  22. xor ax, ax
  23. mov ax, ds
  24. shl ax, 4
  25. add ax, LABEL_GDT ; eax <- gdt 基地址
  26. mov dword [GdtPtr + 2], eax ; [GdtPtr + 2] <- gdt 基地址
  27. ; 加载 GDTR (正式加载到全局描述符表寄存器)
  28. lgdt [GdtPtr]
  29. ; 关中断
  30. cli
  31. ; 打开地址线A20
  32. in al, 92h
  33. or al, 00000010b
  34. out 92h, al
  35. ; 准备切换到保护模式
  36. mov eax, cr0
  37. or eax, 1
  38. mov cr0, eax
  39. ; 真正进入保护模式 (这里就要查询GDTR了,跳转到干货地址)
  40. jmp dword SelectorCode32:0 ; 执行这一句会把 SelectorCode32 装入 cs,
  41. ; 并跳转到 Code32Selector:0
  42. ; END of [SECTION .s16]

2.4 真正的干货

  1. [SECTION .s32]; 32 位代码段. 由实模式跳入.
  2. [BITS 32]
  3. LABEL_SEG_CODE32:
  4. mov ax, SelectorData
  5. mov ds, ax ; 数据段选择子
  6. mov ax, SelectorVideo
  7. mov gs, ax ; 视频段选择子
  8. mov ax, SelectorStack
  9. mov ss, ax ; 堆栈段选择子
  10. mov esp, TopOfStack
  11. 。。。。。。

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

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

3.1.1 GDT定义

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

3.1.2 LDT定义

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

3.2 初始化

  1. ; 初始化 LDT GDT 中的描述符
  2. xor eax, eax
  3. mov ax, ds
  4. shl eax, 4
  5. add eax, LABEL_LDT
  6. mov word [LABEL_DESC_LDT + 2], ax
  7. shr eax, 16
  8. mov byte [LABEL_DESC_LDT + 4], al
  9. mov byte [LABEL_DESC_LDT + 7], ah
  10. ; 初始化 LDT 中的描述符
  11. xor eax, eax
  12. mov ax, ds
  13. shl eax, 4
  14. add eax, LABEL_CODE_A
  15. mov word [LABEL_LDT_DESC_CODEA + 2], ax
  16. shr eax, 16
  17. mov byte [LABEL_LDT_DESC_CODEA + 4], al
  18. mov byte [LABEL_LDT_DESC_CODEA + 7], ah
  19. ; 为加载 GDTR 作准备
  20. xor eax, eax
  21. mov ax, ds
  22. shl eax, 4
  23. add eax, LABEL_GDT ; eax <- gdt 基地址
  24. 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. jsp转发action的问题找不到acton

    -----------------------------jsp转发action的问题找不到acton------------------------------------------- jsp: ...

  2. JavaScript事件处理的三种方式(转)

    一.什么是JavaScript事件? 事件(Event)是JavaScript应用跳动的心脏,也是把所有东西粘在一起的胶水,当我们与浏览器中Web页面进行某些类型的交互时,事件就发生了. 事件可能是用 ...

  3. wchar_t 和 char 之间转换

    vc++2005以后,Visual studio 编译器默认的字符集为Unicode.VC中很多字符处理默认为宽字符wchar_t,如CString的getBuffer(),而一些具体操作函数的输入却 ...

  4. js url图片转bese64

    function convertImgToDataURLviaCanvas(url, callback, outputFormat){ var img = new Image(); img.cross ...

  5. 也来说说C#异步委托(转)

    原文地址: http://www.cnblogs.com/lxblog/archive/2012/12/11/2813893.html 前些日子,看到园子里面有人用老王喝茶的例子讲解了一下同步和异步, ...

  6. extjs tablepanel 高度自适应有关问题

    extjs tablepanel 高度自适应问题 项目中为了给客户好点的功能切换体验,想到了用extjs的tabpanel 在页面中用了tabpanel后,高度新打开的tab页的iframe 的高度总 ...

  7. 上门洗车App 竟然是块大肥肉!

    http://www.leiphone.com/k-xiche-app-idea.html 打车App.租车App.防违规App我们见得多,但洗车App你一定没听过,之前在一次创业路演上碰到一个做上门 ...

  8. NISSAN 尼桑 J1962 诊断座

    J1962诊断座: J1962/16 ........ 常火线 +BATJ1962/  8 ........ 点火开关打开信号 +IGNJ1962/  5 ........ 发动机搭铁线; 逻辑地J1 ...

  9. 数据结构之hash表

    哈希表是种数据结构,它可以提供快速的插入操作和查找操作.hash定义了一种将字符组成的字符串转换为固定长度(一般是更短长度)的数值或索引值的方法,称为散列法,也叫哈希法.由于通过更短的哈希值比用原始值 ...

  10. ubuntu12.04_64bit adb shell

    1.#adb shell 提示error: insufficient permissions for device 解决办法: 1)sudo gedit /etc/udev/rules.d/51-an ...