日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

调用门的定义+调用

發布時間:2023/12/3 编程问答 32 豆豆
生活随笔 收集整理的這篇文章主要介紹了 调用门的定义+调用 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

【0】寫在前面

  • 0.1)本代碼,添加了門描述符的相關代碼,旨在說明 怎樣 對門轉移的目標段 進行定義,調用;
  • 0.2)本文 只對 與 門相關的 代碼進行簡要注釋,言簡意賅;
  • 0.3)文末總結是干貨(from orange’s implemention of a os),前面代碼僅供參考的,且source code from orange’s implemention of a os.

; ========================================== ; pmtest2.asm ; 編譯方法:nasm pmtest2.asm -o pmtest2.com ; ==========================================%include "pm.inc" ; 常量, 宏, 以及一些說明org 0100hjmp LABEL_BEGIN

;全局描述符表定義
[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_CODE_DEST: Descriptor 0,SegCodeDestLen-1, DA_C+DA_32; 非一致代碼段,32
LABEL_DESC_DATA: Descriptor 0, DataLen-1, DA_DRW ; 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 ; 顯存首地址

; 門的定義,緊跟在描述符定義之后
; 門: 目標選擇子,偏移,DCount, 屬性

LABEL_CALL_GATE_TEST: Gate SelectorCodeDest, 0, 0, DA_386CGate+DA_DPL0





;GDT 選擇子定義

......

;門目標段描述符的選擇子定義

SelectorCodeDest equ LABEL_DESC_CODE_DEST - LABEL_GDT

; 門自身選擇子的定義(門也當做一個描述符)
; 這里的干貨是,調用門如何與調用門目標段聯系起來(調用門描述符中的數據結構有選擇子,該選擇子存儲的就是調用門目標段的選擇子)

SelectorCallGateTest equ LABEL_CALL_GATE_TEST - LABEL_GDT

; END of [SECTION .gdt]

;數據段定義 + 全局堆棧段定義 ......

;16位代碼段, CPU運行在實模式下,為什么只有在16位代碼段下才能修改GDT中的值
[SECTION .s16] ; Mine【為從實模式跳轉到保護模式所做的準備工作】

[BITS 16] LABEL_BEGIN:......

; 初始化測試調用門的代碼段(目標段)描述符

xor eax, eaxmov ax, csshl eax, 4add eax, LABEL_SEG_CODE_DESTmov word [LABEL_DESC_CODE_DEST + 2], axshr eax, 16mov byte [LABEL_DESC_CODE_DEST + 4], almov byte [LABEL_DESC_CODE_DEST + 7], ah
......;初始化 LDT 在 GDT 中的描述符 ;Mine【 LABEL_DESC_LDT 作為GDT的表項】xor eax, eaxmov ax, dsshl eax, 4add eax, LABEL_LDTmov word [LABEL_DESC_LDT + 2], axshr eax, 16mov byte [LABEL_DESC_LDT + 4], almov byte [LABEL_DESC_LDT + 7], ah; 初始化 LDT 中的描述符 ; Mine【初始化LDT的基地址所指向的具體的多任務代碼段】xor eax, eaxmov ax, dsshl eax, 4add eax, LABEL_CODE_Amov word [LABEL_LDT_DESC_CODEA + 2], axshr eax, 16mov byte [LABEL_LDT_DESC_CODEA + 4], almov byte [LABEL_LDT_DESC_CODEA + 7], ah;為加載 GDTR 作準備,填充GDT基地址的數據結構xor eax, eaxmov ax, dsshl eax, 4add eax, LABEL_GDT ; eax <- gdt 基地址mov dword [GdtPtr + 2], eax ; [GdtPtr + 2] <- gdt 基地址; 加載 GDTRlgdt [GdtPtr]; 關中斷cli; 打開地址線A20in al, 92hor al, 00000010bout 92h, al; 準備切換到保護模式, PE位置1mov eax, cr0or eax, 1mov cr0, eax; 真正進入保護模式jmp dword SelectorCode32:0 ; 執行這一句會把 SelectorCode32 裝入 cs, 并跳轉到 Code32Selector:0 處; 從保護模式跳回到實模式就到了這里 (注意:從保護模式跳轉到實模式,即本標識符下,本標識符是存在于 初始化描述符的16位代碼段的末尾的) LABEL_REAL_ENTRY: mov ax, csmov ds, axmov es, axmov ss, axmov sp, [SPValueInRealMode]; 關閉 A20 地址線in al, 92h ; and al, 11111101b out 92h, al ; /sti ; 開中斷mov ax, 4c00h ; `.int 21h ; / 回到 DOS

; END of [SECTION .s16]

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

; 32 位代碼段,即保護模式. 由實模式跳入
[SECTION .s32]

[BITS 32]LABEL_SEG_CODE32: ......; 下面顯示一個字符串(此處代碼有省略)

; 測試調用門(無特權級變換),將打印字母 ‘C’

call SelectorCallGateTest:0; call SelectorCodeDest:0
; Mine【這里的LDT選擇子索引的是LDT中記錄的描述符表項的基地址值,即具體任務的執行代碼】; Load LDTmov ax, SelectorLDT ; lldt ax ; Mine【lldt 負責 加載ldtr, 它的操作數是一個選擇子,這個選擇子對應的就是用來描述LDT的那個描述符LABEL_DESC_LDT】; 跳入局部任務jmp SelectorLDTCodeA:0 SegCode32Len equ $ - LABEL_SEG_CODE32

; END of [SECTION .s32]

; 調用門目標段
[SECTION .sdest]

[BITS 32]LABEL_SEG_CODE_DEST:;jmp $mov ax, SelectorVideomov gs, ax ; 視頻段選擇子(目的)mov edi, (80 * 12 + 0) * 2 ; 屏幕第 12 行, 第 0 列。mov ah, 0Ch ; 0000: 黑底 1100: 紅字mov al, 'C'mov [gs:edi], axretfSegCodeDestLen equ $ - LABEL_SEG_CODE_DEST

; END of [SECTION .sdest]

; 16 位代碼段. 由 32 位代碼段跳入, 本段跳出后到實模式
[SECTION .s16code]

ALIGN 32 [BITS 16] LABEL_SEG_CODE16:; 跳回實模式:mov ax, SelectorNormal ; Mine【 選擇子 SelectorNormal 是對描述符 LABEL_DESC_NORMAL 的索引 】mov ds, axmov es, axmov fs, axmov gs, axmov ss, axmov eax, cr0and al, 11111110b ; Mine【cr0的最后一位PE位置為0,進入實模式】mov cr0, eaxLABEL_GO_BACK_TO_REAL:jmp 0:LABEL_REAL_ENTRY ; 段地址會在程序開始處被設置成正確的值 Code16Len equ $ - LABEL_SEG_CODE16

; END of [SECTION .s16code]

; 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 位代碼段),通過索引選擇子SelectorLDTCodeA跳入
[SECTION .la]

ALIGN 32 [BITS 32] LABEL_CODE_A:mov ax, SelectorVideomov gs, ax ; 視頻段選擇子(目的)mov edi, (80 * 12 + 0) * 2 ; 屏幕第 10 行, 第 0 列。mov ah, 0Ch ; 0000: 黑底 1100: 紅字mov al, 'L'mov [gs:edi], ax; 準備經由16位代碼段跳回實模式jmp SelectorCode16:0 CodeALen equ $ - LABEL_CODE_A

; END of [SECTION .la]


總結: (關于門描述符的定義+調用)

  • 1)call指令調用門目標段:這個call指令 在調用門目標段的時候, 被放在進入局部任務之前, 由于我們新加的調用門目標段是以 指令retf 結尾,所以最終代碼將會調回到call 指令的下面繼續執行, 下面就執行局部任務了;(段間 call == [ push ip, push cs, jmp far ptr 標號] , retf == [ pop cs, pop ip ]; 而段內 call == [ push ip, jmp near ptr 標號 ], ret == pop ip )
  • 2)調用門——入口地址: 其實調用門這種聽起來很可怕的東西本質上只不過是一個入口地址而已,只是增加了若干屬性而已。在我們的例子中,完全可以用調用門進行跳轉的指令修改為跳轉到調用門內指定的地址的指令:即 將 call SelectorCallGateTest:0 改為 call SelectorCodeDest:0 ,效果完全一樣。(注:SelectorCallGateTest 是 調用門選擇子, 而SelectorCodeDest 是 調用門目標段選擇子)
  • 3)那么問題 來了: 既然,把跳轉地址從調用門選擇子 改為 調用門目標段選擇子,執行效果相同,那為什么我們還需要調用門呢?
    • 3.1)我們需要用門來實現不同特權級的代碼間的轉移, 因為單純地通過CPL、RPL和RPL進行比較 來進行不同特權級代碼段間的轉移的話,有諸多限制;
    • 3.2)有特權級變換的轉移的復雜之處, 不但在于嚴格的特權級檢驗,還在于特權級變換的時候,堆棧也要發生變化;處理器利用調用門的機制避免了高特權級的過程由于棧空間不足而崩潰;
  • Attention)
  • A1)引入門(調用門)后, 多出了兩個描述符,即門目標段描述符 + 門自身的描述符;
  • A2)引入門(調用門)后,多出了兩個選擇子,即門目標段描述符的選擇子 + 門描述符的選擇子;
  • A3)門目標段描述符的選擇子 + 門描述符的選擇子的作用:

    • A3.1)門目標段描述符的選擇子: 用于索引門目標代碼段,存儲在門描述符數據結構中的選擇子這個數據項,;
    • A3.2)門描述符的選擇子: 用于索引(定位)門(調用門), 為數據段(目標和代碼段)的特權級轉移 提供入口地址而已,
  • A4)(調用)門如何與 門目標段 聯系起來:

    ; 門的定義,緊跟在描述符定義之后 ; 門 目標選擇子,偏移,DCount, 屬性 LABEL_CALL_GATE_TEST: Gate SelectorCodeDest, 0, 0, DA_386CGate+DA_DPL0

    在 門的定義代碼中, 門描述符中的目標選擇子存儲著 門目標段的選擇子,這樣來建立聯系的;

  • A5) 也就是說, 通過調用門和call指令, 可以實現從低特權級到高特權級的轉移,無論目標代碼段是一致的還是非一致的;
    在GDT的定義中,有以下代碼:

    LABEL_DESC_CODE32: Descriptor 0, SegCode32Len-1, DA_C+DA_32; 非一致代碼段,32(98h + 4000h)
    LABEL_CALL_GATE_TEST: Gate SelectorCodeDest, 0, 0, DA_386CGate+DA_DPL0 ;(8Ch + 00h)

從中可以發現,32位 代碼段 描述符LABEL_DESC_CODE32 的屬性 是0100, 0000, 1001, 1000 ; 而(調用)門描述符 LABEL_CALL_GATE_TEST 的屬性是 1000, 1100 ;
通過描述符的數據結構和 門的數據結構,得到 LABEL_DESC_CODE32

總結

以上是生活随笔為你收集整理的调用门的定义+调用的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。