《自己动手写操作系统》源码解析——第三章pmtest5.asm

自己动手写操作系统+源码+工具 自己动手写操作系统pdf+源码+工具,整合到一起,免得大家到处找。 立即下载
在pmtest4中,我们已经看到,对于非一致性代码,如何从低特权级转移向高特权级。但是我们该怎样从高特权级别,转移到低特权级别呢?一开始我们在实模式,是ring 0,我们怎样从ring 0到ring3 ,这个通过call和jmp没法做到,我们该通过什么方式实现?本文,主要是为你解答这些疑问,展现实现这种特权级别转移的方法。通过本节,你将学会如何在特权级之间自由切换。

一、预备理论

1.关于堆栈

我们都知道,可以通过call和jmp实现长跳转或者短跳转(段内转移或者段间转移)。但是jmp和call毕竟是有分别的,其中call指令是会影响到堆栈的:对于短调用,call指令执行时,下一条指令的eip入栈,ret指令执行时候=,这个eip就会从堆栈中弹出。

短调用call指令执行前后堆栈的变化如下图所示(注意带有参数的ret指令):

短调用返回时候的示意图:


长调用的情况与此相似,不同的是call指令执行时,被压栈的还有cs。


2.特权级变换

注意到:如果我们采用call指令进行长跳转,而且特权级别发生了变换,这个时候就发生了堆栈切换,比如从A切换到了B。但是我们的数据保存在A上面,如何从B中返回呢?原来,intel提供了一种机制,能够将A上的一些内容copy到B堆栈中。同时,A堆栈要切换到B堆栈,但是它怎么知道B堆栈在哪里呢答案:原来这个内容保存在任务的TSS结构中,TSS是任务状态段。每个任务都最多有四个堆栈段,但是只有一个esp和ss,TSS就解决了堆栈切换方面的数据保存问题。TSS的相关介绍,可以参考:保护模式及其编程——任务切换http://blog.youkuaiyun.com/trochiluses/article/details/19768579。

示意图如下:



比如,我们目前是ring 3,需要转移到ring 1,那时,堆栈将自动切换到ss1和esp1。(由于只是从外层到内层切换,才从TSS中取得堆栈信息,所以,TSS中没有ring 3相关的堆栈信息。那么从内层向外层切换,如何获得目的地的信息呢?提前压入栈中,来获得返回信息)。

切换过程中有关堆栈的处理,可以参考:保护模式及其编程——保护的详尽意义:通过调用门转移特权级http://blog.youkuaiyun.com/trochiluses/article/details/19573651


二、代码分析

这一部分代码与pmtest4中的代码比较相似,我们仅仅用加粗部分标记改变和增加的代码,没有改变而且不是特别影响逻辑的代码我们直接省略,来进行分析:

; ==========================================


%include "pm.inc"; 常量, 宏, 以及一些说明

org 0100h
jmp LABEL_BEGIN

[SECTION .gdt]
; GDT
;                                         段基址,         段界限     , 属性
LABEL_GDT: Descriptor      0,                   0, 0 ; 空描述符
LABEL_DESC_CODE_RING3:Descriptor       0, SegCodeRing3Len - 1, DA_C + DA_32 + DA_DPL3; 非一致代码段, 32
LABEL_DESC_STACK: Descriptor       0,          TopOfStack, DA_DRWA + DA_32 ; Stack, 32 位;没有标记的stack,实际上是ring 0
LABEL_DESC_STACK3: Descriptor      0,         TopOfStack3, DA_DRWA + DA_32 + DA_DPL3; Stack, 32 位;ring 3
LABEL_DESC_LDT: Descriptor      0,          LDTLen - 1, DA_LDT ; LDT
LABEL_DESC_TSS: Descriptor      0,          TSSLen - 1, DA_386TSS ; TSS
LABEL_DESC_VIDEO: Descriptor0B8000h,              0ffffh, DA_DRW + DA_DPL3; 显存首地址,为了能在ring 3中读写显存,我们改变了显存段的特权级别


; 门                                            目标选择子,       偏移, DCount, 属性
LABEL_CALL_GATE_TEST: Gate SelectorCodeDest,          0,      0, DA_386CGate + DA_DPL3;门描述符的特权级别也是ring 3,不然没法访问
; GDT 结束

GdtLen equ $ - LABEL_GDT ; GDT长度
GdtPtr dw GdtLen - 1 ; GDT界限
dd 0; GDT基地址

; GDT 选择子
SelectorNormal equLABEL_DESC_NORMAL - LABEL_GDT
SelectorCodeRing3equ LABEL_DESC_CODE_RING3- LABEL_GDT + SA_RPL3
SelectorStack3equ LABEL_DESC_STACK3- LABEL_GDT + SA_RPL3
SelectorTSSequ LABEL_DESC_TSS- LABEL_GDT
SelectorCallGateTestequ LABEL_CALL_GATE_TEST- LABEL_GDT + SA_RPL3
; END of [SECTION .gdt]
;========================================================================================================

[SECTION .data1] ; 数据段
SPValueInRealMode dw 0
; 字符串
PMMessage: db "In Protect Mode now. ^-^", 0 ; 进入保护模式后显示此字符串
;*******************************
DataLen equ $ - LABEL_DATA
; END of [SECTION .data1]

===============================================================================================
; 全局堆栈段
[SECTION .gs]
LABEL_STACK:
times 512 db 0
TopOfStack equ$ - LABEL_STACK - 1
; END of [SECTION .gs]
================================================================================================

; 堆栈段ring3
[SECTION .s3]
ALIGN 32
[BITS 32]
LABEL_STACK3:
times 512 db 0
TopOfStack3 equ$ - LABEL_STACK3 - 1
; END of [SECTION .s3]

=================================================================================================
; TSS ---------------------------------------------------------------------------------------------
[SECTION .tss]
ALIGN 32
[BITS 32]
LABEL_TSS:
DD 0; Back
DD TopOfStack; 0 级堆栈
DD SelectorStack; 
DD 0; 1 级堆栈
DD 0; 
; TSS ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
========================================================================================================

[SECTION .s16]
[BITS 16]
LABEL_BEGIN:
mov ax, cs
mov ds, ax
mov es, ax
mov ss, ax
mov sp, 0100h
mov   [LABEL_GO_BACK_TO_REAL+3], ax
mov [SPValueInRealMode], sp

; 初始化 16 位代码段描述符
mov  ax, cs
;********************
mov  byte [LABEL_DESC_CODE16 + 7], ah

; 初始化 32 位代码段描述符
; 初始化测试调用门的代码段描述符
; 初始化数据段描述符
; 初始化堆栈段描述符
; 初始化堆栈段描述符(ring3)
xor eax, eax
mov ax, ds
shl eax, 4
add eax, LABEL_STACK3
mov word [LABEL_DESC_STACK3 + 2], ax
shr eax, 16
mov byte [LABEL_DESC_STACK3 + 4], al
mov byte [LABEL_DESC_STACK3 + 7], ah

; 初始化 LDT 在 GDT 中的描述符
; 初始化 LDT 中的描述符
; 初始化Ring3描述符
xor eax, eax
mov ax, ds
shl eax, 4
add eax, LABEL_CODE_RING3
mov word [LABEL_DESC_CODE_RING3 + 2], ax
shr eax, 16
mov byte [LABEL_DESC_CODE_RING3 + 4], al
mov byte [LABEL_DESC_CODE_RING3 + 7], ah


; 初始化 TSS 描述符
xoreax, eax
mov ax, ds
shl eax, 4
add eax, LABEL_TSS
mov word [LABEL_DESC_TSS + 2], ax
shr eax, 16
mov byte [LABEL_DESC_TSS + 4], al
mov byte [LABEL_DESC_TSS + 7], ah


; 为加载 GDTR 作准备
; 加载 GDTR
; 关中断
; 打开地址线A20
; 准备切换到保护模式
; 真正进入保护模式
jmp dword SelectorCode32:0; 执行这一句会把 SelectorCode32 装入 cs, 并跳转到 Code32Selector:0  处
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

LABEL_REAL_ENTRY: ; 从保护模式跳回到实模式就到了这里
mov ax, cs
关闭 A20 地址线
; 开中断

; ┛回到 DOS
; END of [SECTION .s16]
==============================================================================================

[SECTION .s32]; 32 位代码段. 由实模式跳入.
[BITS
32]
LABEL_SEG_CODE32:
movax, SelectorData
movds, ax ; 数据段选择子
; 视频段选择子
         ; 堆栈段选择子
movesp, TopOfStack

; 下面显示一个字符串
; 显示完毕
call DispReturn
; Load TSS
movax, SelectorTSS

ltrax ; 在任务内发生特权级变换时要切换堆栈,而内层堆栈的指针存放在当前任务的TSS中,所以要设置任务状态段寄存器 TR。


pushSelectorStack3 ;ss3
push TopOfStack3 ;sp3
push SelectorCodeRing3 ;cs3
push 0 ;Eip
retf ; Ring0 -> Ring3,历史性转移!将打印数字 '3'。

注意:这一个关键的retf指令,它弹出两个值,一个给EIP,另一个给ECS;通过这种方式,转移到ring 3;这里要特别关注retf指令,它用于长返回,而且可以用于带有特权级别变换的长返回。上面之所以要push 4个参数,是因为retf要用到这四个参数。之所以要loadTSS,是因为待会还要从ring3回到ring 0.


另外,需要特别注意的是此处的TSS;如果没有TSS,我们只能从高特权级别转向低特权级;没法从低特权级别转向高特权级别。也就是说,如果涉及到堆栈切换,那么必须要用到TSS。我们可以将ltr ax这句注释掉,然后查看结果(见最后一副图)。


; ------------------------------------------------------------------------

SegCode32Len equ$ - LABEL_SEG_CODE32
; END of [SECTION .s32]


;=======================================================================================================

[SECTION .sdest]; 调用门目标段
[BITS 32]

LABEL_SEG_CODE_DEST:
mov ax, SelectorVideo
mov gs, ax; 视频段选择子(目的)
movedi, (80 * 12 + 0) * 2 ; 屏幕第 12 行, 第 0 列。
mov ah, 0Ch; 0000: 黑底    1100: 红字
mov al, 'C'
mov [gs:edi], ax
; Load LDT
mov ax, SelectorLDT
lldt ax
jmpSelectorLDTCodeA:0 ; 跳入局部任务,将打印字母 'L'。
;retf
SegCodeDestLenequ $ - LABEL_SEG_CODE_DEST
; END of [SECTION .sdest]
======================================================================================

; 16 位代码段. 由 32 位代码段跳入, 跳出后到实模式
[SECTION .s16code]
ALIGN 32
[BITS 16]
LABEL_SEG_CODE16:
; 跳回实模式:
mov ax, SelectorNormal
;******************************************
LABEL_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 equLABEL_LDT_DESC_CODEA - LABEL_LDT + SA_TIL
; END of [SECTION .ldt]

==================================================================================
; CodeA (LDT, 32 位代码段)
[SECTION .la]
ALIGN 32
[BITS 32]
LABEL_CODE_A:
mov ax, SelectorVideo
mov gs, ax; 视频段选择子(目的)
movedi, (80 * 13 + 0) * 2 ; 屏幕第 13 行, 第 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]

=======================================================================================

; CodeRing3
[SECTION .ring3]
ALIGN 32
[BITS 32]
LABEL_CODE_RING3:
mov ax, SelectorVideo
mov gs, ax; 视频段选择子(目的)
movedi, (80 * 14 + 0) * 2 ; 屏幕第 14 行, 第 0 列。
mov ah, 0Ch; 0000: 黑底    1100: 红字
mov al, '3'
mov [gs:edi], ax

callSelectorCallGateTest:0 ; 测试调用门(有特权级变换),将打印字母 'C'。

jmp$ ;注意:程序将停在这里


SegCodeRing3Lenequ $ - LABEL_CODE_RING3
; END of [SECTION .ring3]


程序的大致执行过程如下:

保护模式下进入16b的代码段,ring=0,初始化相关段描述符、门描述符、ldt描述符、数据段描述符、堆栈段描述符、ldt中的描述符、ring 3的代码段描述符TSS描述符;加载gdt,通过长jmp,进入保护模式,进入32b的代码段,ring =0:初始化数据段、堆栈段、视频段的选择子寄存器;显示一个字符串;load TSS;利用retf指令,从ring 0转移到ring 3的代码段:在代码段中显示‘3’,然后通过调用门进入ring 0的代码段:打印字母C,然后通过jmp跳转到局部代码段:打印字母‘L’;程序回到ring 3,成为循环。


查看运行结果:我们第一次进入了不同的特权级。


下图:注释TSS的结果,可以看到可以从ring 0进入ring 3;但是无法从ring 3进入ring 0.


自己动手写操作系统(含源代码) 自己动手写操作系统(含源代码)。很不错的资源。 立即下载

相关推荐

《自己动手写操作系统》源码(0币)

《自己动手写操作系统》源码(0币)

pmtest5.asm

; ==============带特权级变换的调用门==============; pmtest5.asm; 编译方法:nasm pmtest5.asm -o pmtest5.com;; 执行过程:                  门;    16位实模式---->CODE32(ring0)---->CODE_RING3(ring3)----------->CODE_DEST(ring0)---

世界上有两种人,一种是改变世界的人,另一种是被世界同化的人! 709

GEOS-Chem笔记——模式下载安装+驱动数据+运行流程

看过我博客的会发现我写了很多CESM的笔记,但是说实话,平时科研我其实更多时候是GEOS-Chemuser。之所以写了很多CESM笔记,其实是因为不会,就边学边写。然后GEOS-Chem已经用比较熟了,所以也没想过做笔记啥的。但是我发现越来越多朋友私信我各种CESM问题,我觉得我可能给大家营造了一种我是CESM达人的错觉。感觉自己有点跑偏了呢。公平起见,我觉得我有必要补充点GEOS-Chem笔记。 GEOS-Chem是研究大气化学的人常用的大气化学传输模式,在全世界范围的大气化学研究组中被广泛使用。不过.

砍柴姑娘Jourosy的博客 1万+

《自己动手写操作系统》——制作一个简单的操作系统

将一段显示字符串的汇编代码编译成二进制,并制作成镜像文件;安装虚拟机软件,加载镜像文件,输出字符串不符合预期;通过反汇编发现,目前的10H中断需要额外指定cx寄存器的值;org 07c00h的作用是告诉汇编器这段代码将会加载在段内偏移地址为7c00处的内存中,因此需要将代码中所有地址都进行这个偏移。要正确反汇编一个’DOS.COM’文件,反汇编器必须知道文件中的第一条指令是被装载到内存何处,ndisasm缺省地认为你给它的每一个文件都是装载到0处的,所以你必须告诉它这一点。'-o'

UCAS_HMM的博客 2510

使用SSE流式输出(Javaweb前后端实战)

SSE(Server-Sent Events)是一种在Web应用中实现单向实时通信的技术。通过SSE,服务器可以主动向客户端发送更新,而无需客户端不断发起请求。这对于需要实时更新的应用场景(如聊天应用、实时数据监控等)非常有用。(服务端单向传输客户端,长连接)

记得开心一点嘛的博客 1万+

WPS Office 2019 For Linux二次开发全流程:从源码下载到Demo运行

本文详细介绍了在Linux环境下进行WPS Office 2019 C++二次开发的全流程,涵盖从开发环境准备、源码获取、核心依赖(Qt与WPS)安装配置,到最终编译运行官方Demo的完整步骤。文章重点解析了环境搭建中的常见问题与解决方案,旨在帮助开发者快速上手WPS二次开发。

weixin_29001423的博客 390

[自己动手写操作系统]的学习实践【第三章】

因为第二章主要是讲系统的一些配置,所以我们在这里就不准备怎么费多少笔墨描述了,第三章 保护模式第一节  认识保护模式本章我们要学习计算机如何由实模式转入保护模式。实模式向保护模式的转变需要更改一系列的参数。实质是通过一个数据结构来使得16位寄存器访问了4GB的空间。我们下面的程序就显示了这个例子。我们对此的分析将以旁注的方式表现。; ========================

“秋天的叶子”的专栏 896

RC模型车多电机驱动方案:从电调PWM原理到四电机安全连接实战

在电机控制领域,PWM(脉冲宽度调制)是实现精确调速的核心技术。其原理是通过调节固定周期内高电平的脉宽来编码控制指令,进而驱动电子调速器(电调)改变输出功率。这项技术对于需要多电机协同工作的场景,如RC模型车的差速转向或重型负载驱动,具有关键价值。它能实现动力的精细分配与同步,提升车辆的可控性与通过性。在实际应用中,为确保系统稳定,必须关注电流分配与信号同步问题。例如,通过为每个电机配备独立电调并采用信号并联(Y线)的方式,可以构建可靠的四电机驱动系统。这种方案能有效避免因单个电调过载或电机反电动势不一致导

weixin_30664615的博客 382

http://blog.youkuaiyun.com/zgh1988/article/details/7098981

[置顶]全面剖析《自己动手写操作系统》第三章---保护模式                分类:            操作系统2011-12-24 00:30649人阅读评论(16)收藏举报 《自己动手写操作系统》读后感                http://blog.youkuaiyun.com/zgh1988/article/details/7059936 全面剖析《自己动手写操

yu_chenglong的专栏 1095

逆向工程实战:如何用Frida和IDA破解AppleAccount的X-MMe-Nas-Qualify签名机制

本文通过逆向工程实战,详细解析了如何利用Frida动态Hook和IDA静态分析技术,破解AppleAccount服务中关键的X-MMe-Nas-Qualify签名机制。文章从环境搭建、动态追踪NSMutableURLRequest的签名注入点开始,逐步深入到AuthKit框架的静态剖析与算法还原,最终实现独立的签名生成,为安全研究和自动化测试提供了完整的技术路径。

bush的博客 696

rk3588 rkaiq_3A_server 无法解析json文件记录

rk3588 rkaiq_3A_server 无法解析json文件记录

neardi_dev的博客 1万+

《自己动手写操作系统》第三章 pmtest1——从实模式到保护模式

摘要:本节,我们将学习如何从实模式进入保护模式,剖析pmtest1.asm源码。详细讲解如何从保护模式进入实模式。 1.头文件编写: 这一部分,你需要把一些关键物理器件和数据结构的布局记在脑子里 GDT描述符:32b段基地址(B2、B3、B4、B7)+20b段限长(B0、B1、B6的低4位)+12b段属性(B5、B6的高4位),详细布局见下图(针对代码段和数据段): 所

河西无名式 3738

Python爬虫实战:使用Scrapy+Playwright高效爬取全球石油价格历史数据

python复制下载# 产品信息# 日期信息# 价格数据price = scrapy.Field() # 收盘价open = scrapy.Field() # 开盘价high = scrapy.Field() # 最高价low = scrapy.Field() # 最低价volume = scrapy.Field() # 交易量change_percent = scrapy.Field() # 涨跌幅# 元数据。

2201_76125261的博客 1020

《自己动手写操作系统》第三章 pmtest5源码解析——特权级变换与堆栈切换实例详解

摘要:在pmtest4中,我们已经看到,对于非一致性代码,如何从低特权级转移向高特权级。但是我们该怎样从高特权级别,转移到低特权级别呢?本文,主要是为你解答这些疑问,展现实现这种特权级别转移的方法。另外,我们将在实践中探讨,为什么要设定RPL,是不是相对与DPL多此一举呢?在调试环节,我们将通过改动代码,排查相关错误来深入理解特权级检测机制。 一、预备理论1.关于堆栈 我们都知道,可以通过cal

河西无名式 2204

harbor x509: certificate signed by unknown authority【20251222】

本教程通过「合并证书链(服务器端)+ 预置根 CA(客户端)」彻底解决了自签名证书的 x509 错误,同时集成了 Trivy 漏洞扫描,实现了 Harbor 从搭建到实用的全流程。证书链合并是服务器端的关键,确保客户端获取完整信任路径;客户端需同时配置「系统信任库 + Docker 信任目录」,避免 Docker 独立信任机制导致的问题;所有 IP 需保持一致(Harbor 配置、证书绑定、客户端访问),是避免错误的基础。

老韩的Linux云计算架构师进阶之路 682

Data-Structures-and-Algorithm-Analysis-in-Java.pdf

作者: Weiss, Mark A. 出版社: Addison Wesley Data Structures and Algorithm Analysis in Java is an “advanced algorithms” book that fits between traditional CS2 and Algorithms Analysis courses. In the old ACM Curriculum Guidelines, this course was known as CS7. This text is for readers who want to learn good programming and algorithm analysis skills simultaneously so that they can develop such programs with the maximum amo...

读《自己动手写操作系统》

  用一个月左右的时间读了《自己动手写操作系统》,这是一本让人读着很过瘾,却也特别累的一本书。http://ike.126.com  对操作系统的兴趣由来已久,只是一直未能找到入门之径。操作系统教材是个令人生畏的东西,它可以告诉人有什么,却不能告诉人为什么,从那里了解的操作系统有如盲人摸到的象,得到各个部分,却不能拥有整体,加之缺乏实践的支持,理论显得苍白空洞。如Linux般的开源操作系统

净心编程 9647

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

通过调用门进行有特权级变换的转移,详细注解 对pmtest5.asm解释很详细.

http://www.myexception.cn/operating-system/484288.html http://www.myexception.cn/operating-system/445331.html http://www.myexception.cn/operating-system/445078.html 代码总体过程如下: 1.进入保护模式,显示字符In Pr...

weixin_33989780的博客 215

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

pmtest4.asm

;====================================== ;pmtest4.asm ;编译方法:nasm pmtest4.asm -o pmtest4.bin ;====================================== %include "pm.inc"; 常量,宏 以及一些说明 ;org 07c00h org 0100h jmp LABEL_B...

lhm的博客 533

orange's学习--第三章:e pmtest5.asm设置TSS通过调用门进行低特权级到高特权级的转移

由低特权级到高特权级切换时新堆栈会从TSS中取得,由高特权级到低特权级切换时,需要从当前堆栈中弹出调用者的ss和sp。 除了0级堆栈之外,其他各个字段我们都没做任何初始化。因为在本例中,我们只用到这一部分。 TSS作为一个段存在,需要设置GDT内容和段选择子,然后进行加载 LABEL_DESC_TSS: Descriptor 0, TSSLen-1, DA...

交换ab:a=a^b;b=a^b;a=a^b; 373

pmtest5

Code;==========================================;pmtest5.asm;编译方法:nasmpmtest5.asm-opmtest5.com;==========================================%include"pm.inc";常量,宏,以及一些说明org0100hjm...

weixin_34152820的博客 213

【学习】【保护模式编程、四】

【LDT描述符&&特权级&&门】一、LDT(局部描述符)GDT是全局描述符,是整个系统的描述符,描述符着所有的段!!!在前几章我们已经熟悉了GDT的一些基本功能,与运作机制。对GDT描述符的定义与使用也就那么几项固定的步骤,接下来再了解LDT.LDT是局部描述符。看字面LDT与GDT很相似.它们都是描述符。只不过GDT是全局描述符、而LDT是局部描述符。那么LDT该如何

zhusongdong的专栏 2449

操作系统实践(5)——关于LDT

LDT与GDT类似,为局部描述符表。使用LDT有几个步骤: 1.在GDT中加一个表项,并增加一个描述符,假设为SelectorLDT; 2.像配置GDT表那样,配置好LDT表自己的描述符,并设置好相应的ldt的选择子,选择子有一位标识是ldt还是gdt; 3.加载LDT,使用lldt指令; 4.直接jmp ldt里面的选择子。跳转到LDT里的代码段,跟用GDT跳转代码段一样,都是通过 j

最帅惋红曲 1606

自己动手写操作系统(高清图书+源代码)分享

很喜欢《自己动手写操作系统》这本书,但现在这本书已经绝版了。在这里分享一下这本书的高清电子版和源代码,感兴趣的人可以下载一下。 链接:https://pan.baidu.com/s/1lPXg-Airu2NFjSaTwX67jQ 提取码:sdfr 复制这段内容后打开百度网盘手机App,操作更方便哦 ...

qq_42884482的博客 9698
上一篇: 自己动手写操作系统源码剖析——第三章 pmtest4.asm
下一篇: int 15h中断获取内存信息
谁不小心的
码龄15年 462粉丝 246原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值