段描述符表(GDT+LDT)的有感
【0】寫(xiě)在前面
要知道,在匯編中,代碼的裝入順序決定了在內(nèi)存中的地址位置。所有的代碼或者數(shù)據(jù)都在硬盤(pán)上,當(dāng)調(diào)試或者啟動(dòng)的時(shí)候,加載到內(nèi)存;當(dāng)需要對(duì)數(shù)據(jù)進(jìn)行處理的時(shí)候,我們通過(guò)將數(shù)據(jù)從內(nèi)存載入到registers 通過(guò)cpu來(lái)進(jìn)行處理的。
【1】初始化各種段描述符
以 初始化 32 位代碼段描述符 為例
【2】有感
首先:要先定義這段描述符(占據(jù)內(nèi)存空間),然后向里面?zhèn)魅胝嬲幚頂?shù)據(jù)的地址;
2.1 定義階段
為什么 LABEL_GDT 必須跟在最前面呢?
因?yàn)樗牡刂芬鳛槎蔚幕刂?#xff0c;而選擇子的地址作為偏移地址來(lái)定位某個(gè)段。你想想你C語(yǔ)言的數(shù)組,是不是這樣排列的。首先數(shù)組首地址在開(kāi)頭,然后后面存儲(chǔ)的是元素的地址,呵呵。碉堡了。一句話(huà)說(shuō)完;
LABEL_GDT: Descriptor 0, 0, 0 ; 空描述符
只要吧LABEL_GDT放在某段內(nèi)存的起始位置,跟在它后面的哪些段描述符(內(nèi)存地址),都可以作為GDT中的元素(或者稱(chēng)為表項(xiàng)),這就是一個(gè)表(或者數(shù)組)的定義由來(lái)。LABEL_DESC_CODE32: Descriptor 0, SegCode32Len - 1, DA_C + DA_32 ; 非一致代碼段, 32
2.2 定義選擇子
說(shuō)白了,選擇子就是某個(gè)段相對(duì)于全局描述符GDT的偏移地址; 當(dāng)我們知道GDT的地址后,將其作為基地址,并將選擇子作為偏移地址,來(lái)定位該段描述符的。
; GDT 選擇子 SelectorCode32 equ LABEL_DESC_CODE32 - LABEL_GDT2.3 往段描述符空間裝干貨地址
干貨就是真正的處理數(shù)據(jù)的代碼。(如向屏幕顯示打印字符)
[SECTION .s16] [BITS 16] LABEL_BEGIN:;start point: jmp會(huì)跳到這里 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 作準(zhǔn)備(將全局描述符表GDT裝入全局描述符表寄存器GDTR,目的是跳轉(zhuǎn)的時(shí)候,程序要到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]; 關(guān)中斷 cli; 打開(kāi)地址線(xiàn)A20in al, 92h or al, 00000010b out 92h, al; 準(zhǔn)備切換到保護(hù)模式 mov eax, cr0 or eax, 1 mov cr0, eax; 真正進(jìn)入保護(hù)模式 (這里就要查詢(xún)GDTR了,跳轉(zhuǎn)到干貨地址) jmp dword SelectorCode32:0 ; 執(zhí)行這一句會(huì)把 SelectorCode32 裝入 cs,; 并跳轉(zhuǎn)到 Code32Selector:0 處 ; END of [SECTION .s16]2.4 真正的干貨
[SECTION .s32]; 32 位代碼段. 由實(shí)模式跳入. [BITS 32] LABEL_SEG_CODE32: mov ax, SelectorData mov ds, ax ; 數(shù)據(jù)段選擇子 mov ax, SelectorVideo mov gs, ax ; 視頻段選擇子 mov ax, SelectorStack mov ss, ax ; 堆棧段選擇子 mov esp, TopOfStack 。。。。。。【3】GDT + LDT (全局描述符表+局部描述符表) from p49.asm
3.1 GDT的首地址(基地址)定義, 跟在它后面的都是其表項(xiàng)
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 結(jié)束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 作準(zhǔn)備 xor eax, eax mov ax, ds shl eax, 4 add eax, LABEL_GDT ; eax <- gdt 基地址 mov dword [GdtPtr + 2], eax ; [GdtPtr + 2] <- gdt 基地址總結(jié)
以上是生活随笔為你收集整理的段描述符表(GDT+LDT)的有感的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 微软 Win11 中 Copilot 初
- 下一篇: 库克看好Vision Pro头显前景 称