GDT是保护模式下的内存段登记表。
段界限计算
段界限用 20 个二进制位来表示。只不过此段界限只是个单位量,它的单位要么是字节,要么是 4K,这是由描述符中的G位来指
定的。由于段界限只是个偏移量,是从 算起所以实际的段界限边界值=
(描述符中段界限+1) * (段界限的粒度大小: 4k或者 1) -1
这个公式很简单,就是表示有多少个 4KB 由于描述符中的段界限是从 起的,所以左边第个括号中要加个 ,表示 4KB 的实际数量。它与第二个括号中的段粒度大小相乘后得到的乘积是以
为起始的段的实际大小 由于地址是以0为起始的,所以公式的最后又减了1.
如果G位为 1,表示段界限粒度大小为 4KB 字节,故实际段界限=(描述符中段界限+ 1) k-1
个例子,如果是平坦模型,段界限为 OxFFFFF, 位为 ,套用上面公式,段界限边界值=0x100000*0x1000-1 =0xFFFFFFFF =4G
段属性被拆分是由于历史原因。
段基地址要进行拼接才行形成完整的基地址。
GDT表属性
undefined
;————– gdt描述符属性 ————-
DESC_G_4K equ 1_00000000000000000000000b ;G位为1,4K粒子
DESC_D_32 equ 1_0000000000000000000000b ;DB位为1,32位系统
DESC_L equ 0_000000000000000000000b ;64位代码标记,此处标记为0便可。
DESC_AVL equ 0_00000000000000000000b ;cpu不用此位,暂置为0
DESC_LIMIT_CODE2 equ 1111_0000000000000000b ;代码段高32位长度F
DESC_LIMIT_DATA2 equ DESC_LIMIT_CODE2 ;数据段高32位长度F
DESC_LIMIT_VIDEO2 equ 0000_000000000000000b ;
DESC_P equ 1_000000000000000b ;P位在内存
DESC_DPL_0 equ 00_0000000000000b ;访问权限
DESC_DPL_1 equ 01_0000000000000b
DESC_DPL_2 equ 10_0000000000000b
DESC_DPL_3 equ 11_0000000000000b
DESC_S_CODE equ 1_000000000000b ;S位是系统段
DESC_S_DATA equ DESC_S_CODE
DESC_S_sys equ 0_000000000000b ;非系统段,是代码段或数据段
DESC_TYPE_CODE equ 1000_00000000b ;x=1,c=0,r=0,a=0 代码段是可执行的,非依从的,不可读的,已访问位a清0.
DESC_TYPE_DATA equ 0010_00000000b ;x=0,e=0,w=1,a=0 数据段是不可执行的,向上扩展的,可写的,已访问位a清0.
;以下为系统代码段,数据段,显存段选择子的高32位初始化
undefined
DESC_CODE_HIGH4 equ (0x00 << 24) + DESC_G_4K + DESC_D_32 + DESC_L + DESC_AVL + DESC_LIMIT_CODE2 + DESC_P + DESC_DPL_0 + DESC_S_CODE + DESC_TYPE_CODE + 0x00
DESC_DATA_HIGH4 equ (0x00 << 24) + DESC_G_4K + DESC_D_32 + DESC_L + DESC_AVL + DESC_LIMIT_DATA2 + DESC_P + DESC_DPL_0 + DESC_S_DATA + DESC_TYPE_DATA + 0x00
DESC_VIDEO_HIGH4 equ (0x00 << 24) + DESC_G_4K + DESC_D_32 + DESC_L + DESC_AVL + DESC_LIMIT_VIDEO2 + DESC_P + DESC_DPL_0 + DESC_S_DATA + DESC_TYPE_DATA + 0x0b
;0x00 << 24 是填充高32位31-24的段基地址都为0
GDT表实现
;构建gdt及其内部的描述符
GDT_BASE: dd 0x00000000
dd 0x00000000
CODE_DESC: dd 0x0000FFFF
dd DESC_CODE_HIGH4
DATA_STACK_DESC: dd 0x0000FFFF
dd DESC_DATA_HIGH4
VIDEO_DESC: dd 0x80000007 ;limit=(0xbffff-0xb8000)/4k=0x7
dd DESC_VIDEO_HIGH4 ; 此时dpl已改为0
GDT_SIZE equ $ - GDT_BASE
GDT_LIMIT equ GDT_SIZE - 1
dq 50 dup(0) ;不能预留 60个 ,60 * 8B 太大了(只有1M内存),50可以运行正常。
; times 60 dq 0 ; 此处预留60个描述符的slot
SELECTOR_CODE equ (0x0001<<3) + TI_GDT + RPL0 ; 相当于(CODE_DESC - GDT_BASE)/8 + TI_GDT + RPL0
SELECTOR_DATA equ (0x0002<<3) + TI_GDT + RPL0 ; 同上
SELECTOR_VIDEO equ (0x0003<<3) + TI_GDT + RPL0 ; 同上
GDT_BASE:规定第一个GDT元素必须为全0,预防一些错误。
CODE_DESC:系统代码段,基地址为全0,段界限 可以访问 0- 4G
DATA_STACK_DESC:栈段和数据段,可以访问0-4G,后面在操作系统初始化时会修改栈地址。
VIDEO_DESC:显存段
访问每个GDT元素需要通过选择子进行访问,将选择子加载到段寄存器中,所以有了下面的几个SELECTOR。
计算GDT_LIMIT 是用于将GDT加载到GDT寄存器中
Original: https://www.cnblogs.com/thotf/p/16289706.html
Author: thotf
Title: GDT表实现
原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/582260/
转载文章受原作者版权保护。转载请注明原作者出处!