段描述符表(GDT+LDT)的有感
生活随笔
收集整理的這篇文章主要介紹了
段描述符表(GDT+LDT)的有感
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
【0】寫在前面
要知道,在匯編中,代碼的裝入順序決定了在內存中的地址位置。所有的代碼或者數據都在硬盤上,當調試或者啟動的時候,加載到內存;當需要對數據進行處理的時候,我們通過將數據從內存載入到registers 通過cpu來進行處理的。
【1】初始化各種段描述符
以 初始化 32 位代碼段描述符 為例
【2】有感
首先:要先定義這段描述符(占據內存空間),然后向里面傳入真正處理數據的地址;
2.1 定義階段
為什么 LABEL_GDT 必須跟在最前面呢?
因為它的地址要作為段的基地址,而選擇子的地址作為偏移地址來定位某個段。你想想你C語言的數組,是不是這樣排列的。首先數組首地址在開頭,然后后面存儲的是元素的地址,呵呵。碉堡了。一句話說完;
LABEL_GDT: Descriptor 0, 0, 0 ; 空描述符
只要吧LABEL_GDT放在某段內存的起始位置,跟在它后面的哪些段描述符(內存地址),都可以作為GDT中的元素(或者稱為表項),這就是一個表(或者數組)的定義由來。LABEL_DESC_CODE32: Descriptor 0, SegCode32Len - 1, DA_C + DA_32 ; 非一致代碼段, 32
2.2 定義選擇子
說白了,選擇子就是某個段相對于全局描述符GDT的偏移地址; 當我們知道GDT的地址后,將其作為基地址,并將選擇子作為偏移地址,來定位該段描述符的。
; GDT 選擇子 SelectorCode32 equ LABEL_DESC_CODE32 - LABEL_GDT2.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; 打開地址線A20in 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)的有感的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 微软 Win11 中 Copilot 初
- 下一篇: 转移指令jmp和跳转指令call