直接上代码,以及追加了自己对GDT的理解,为了理解GDT,翻遍了各种文章,但没有代码的支撑,凭空的理解很浪费时间。

下面的代码,稍微简化了原先的代码(于老师的代码^^)。把pm.asm需要的代码从pm.inc挪出来,取消了pm.inc的引入。

; ==========================================
; 32mode_TEXT.asm
; 编译方法:nasm 32mode_TEXT.asm -o 32mode_TEXT.bin
; ==========================================;=========================宏定义:  GDT的定义 开始=====================================
;
; 描述符 类型       入参1(%1), 入参2(%2), 入参3(%3)
; usage: Descriptor  Base,       Limit,       Attr
;        Base:  dd
;        Limit: dd (low 20 bits available)
;        Attr:  dw (lower 4 bits of higher byte are always 0)
%macro Descriptor 3dw   %2 & 0FFFFh             ; 段界限1(双字节:字节1~字节2)dw  %1 & 0FFFFh             ; 段基址1(双字节:字节3~字节4)db  (%1 >> 16) & 0FFh         ; 段基址2(单字节:字节5)dw  ((%2 >> 8) & 0F00h) | (%3 & 0F0FFh)   ; 属性1 + 段界限2 + 属性2(双字节:字节6~字节7)db    (%1 >> 24) & 0FFh         ; 段基址3(单字节:字节8)
%endmacro ; 共 8 字节
;
; 门     类型   入参1,  入参2,  入参3,  入参4
; usage: Gate Selector, Offset, DCount, Attr
;        Selector:  dw
;        Offset:    dd
;        DCount:    db
;        Attr:      db
%macro Gate 4    ; 4为参数个数dw (%2 & 0FFFFh)               ; 偏移1 (双字节)dw %1                  ; 选择子(双字节)dw  (%3 & 1Fh) | ((%4 << 8) & 0FF00h) ; 属性  (双字节)dw ((%2 >> 16) & 0FFFFh)         ; 偏移2 (双字节)
%endmacro ; 共 8 字节
;=========================GDT的定义 结束=====================================
org 07c00hjmp LABEL_BEGIN[SECTION .gdt]
; GDT
; Descriptor在pm.inc中定义,三个入参
; LABEL_GDT为(0#)描述符,创建0#描述符,它是空描述符,这是处理器的要求
;                               段基址,      段界限         , 属性
LABEL_GDT:     Descriptor     0,      0,                 0          ; 空描述符
LABEL_DESC_CODE32: Descriptor     0,      SegCode32Len - 1,  98h + 4000h; 非一致代码段
LABEL_DESC_VIDEO:  Descriptor   0B8000h,  0ffffh,        92h    ; Text显存首地址:0B8000h,VGA显存首地址:0x000a0000
; GDT 结束GdtLen      equ $ - LABEL_GDT   ; GDT长度
GdtPtr      dw  GdtLen - 1      ; GDT界限dd  0        ; GDT基地址; GDT 选择子
; LABEL_GDT的地址为GDT表起始地址
; 后面的GDT的地址,都是以LABEL_GDT的地址为起始地址,计算自己的地址
SelectorCode32      equ LABEL_DESC_CODE32 - LABEL_GDT
SelectorVideo       equ LABEL_DESC_VIDEO  - LABEL_GDT
; END of [SECTION .gdt][SECTION .s16]
[BITS   16]
LABEL_BEGIN:mov ax, csmov ds, axmov es, axmov ss, axmov sp, 0100h; 初始化 32 位代码段描述符; xor eax,eax和mov eax,0一样,由于它比mov eax,0效率高,所以一般用它!; 两者的作用没有区别,都是让eax的值为0,但是xor eax,eax 指令为2字节,mov eax,0 指令为5个字节。相比而言,前面指令更能节省空间。; 这个虽然结果是一样的,都是变成0,但是xor会影响到状态标志位,使cf of 变成0。xor eax, eaxmov ax, csshl eax, 4 ; shl:逻辑左移指令 shr:逻辑右移指令add eax, LABEL_SEG_CODE32mov word [LABEL_DESC_CODE32 + 2], axshr eax, 16mov byte [LABEL_DESC_CODE32 + 4], almov byte [LABEL_DESC_CODE32 + 7], ah; 为加载 GDTR 作准备xor eax, eax; “XOR EAX,EAX”语句已经将EAX清零了。mov ax, ds  ; 然后“MOV AX,DS”将16位的段值从DS复制到AX。shl eax, 4  ; “SHL EAX,4”是计算数据段的起始物理地址,; 所以用了EAX来表示20位的物理地址(没有使用AX表示物理地址是因为AX只有16位)。 ; (注:实模式下的寻址的方式固然还是段:偏移,而且段:偏移还都是16位,; 但在实模式下却可以使用32位寄存器,如EAX……等,; 而这里的EAX既不是段值,也不是偏移,而是人工计算出的物理地址,; 相当于用EAX保存的数据,; 最后再通过“MOV DWORD[GdtPtr+2],EAX”将EAX中的物理地址送到DS:(OFFSET GdtPtr)+2表示的逻辑地址处。)add eax, LABEL_GDT      ; eax <- gdt 基地址mov dword [GdtPtr + 2], eax ; [GdtPtr + 2] <- gdt 基地址; 加载 GDTRlgdt    [GdtPtr]; 关中断cli; 打开地址线A20; 打开A20的其他方法:https://blog.csdn.net/longintchar/article/details/79365928; 下面写法是其中之一in  al, 92h  ;南桥芯片内的端口 or  al, 00000010bout 92h, al; 准备切换到保护模式--除了cr0还有其他控制寄存器(CR0,CR1,CR2,CR3,CR4)mov eax, cr0; cr0是80386CPU中的控制寄存器or  eax, 1  ; 第0位,即PE位,用来控制是否进入保护模式(是/否:1/0)mov cr0, eax; 设置PE位; 真正进入保护模式jmp dword SelectorCode32:0  ; 执行这一句会把 SelectorCode32 装入 cs,; 并跳转到 SelectorCode32:0  处; 【jmp dword SelectorCode32:0】的理解; http://tieba.baidu.com/p/4302738682; SelectorCode32:0的意思就是第二个描述符的第0行代码开始,这里的0是不是可以换成32位模式下的任何函数?
; END of [SECTION .s16][SECTION .s32]; 32 位代码段. 由实模式跳入.
[BITS   32]LABEL_SEG_CODE32:mov ax, SelectorVideomov gs, ax          ; 视频段选择子(目的)mov ecx, 28         ; .show的循环次数mov edi, 0mov bx, BootMessage
.show:mov ah, 0Ch         ; 0000: 黑底    1100: 红字mov al, [bx]mov [gs:edi], axinc ediinc ediinc bxloop .show; 到此停止jmp $BootMessage:        db  "Hello CPU, I'm in protected mode!"
SegCode32Len    equ $ - LABEL_SEG_CODE32
; END of [SECTION .s32]

用GDB查看GDT的内容(64位GCC在Windows下模拟)

GDT和段的关系

代码:
mov ax, SelectorVideo ; SelectorVideo 为LABEL_DESC_CODE32的选择子
mov gs, ax                   ; gs指向GDT(LABEL_DESC_CODE32)的段基址
这时gs指向0x000b8000, 即段描述符的段基址。界限值:0xffff
剩下就和正常的段寄存器操作一样了。
gs:edi等

学习操作系统:进入保护模式,理解GDT(1):TEXT相关推荐

  1. 操作系统——认识保护模式

    操作系统--认识保护模式 实验目的及内容 认真阅读章节资料,掌握什么是保护模式,弄清关键数据结构:GDT.descriptor.selector.GDTR, 及其之间关系,阅读pm.inc文件中数据结 ...

  2. 操作系统——让操作系统走进保护模式

    操作系统--让操作系统走进保护模式 实验内容: 向软盘镜像文件写入一个你指定的文件,手工读取在磁盘中的信息 在软盘中找到指定的文件,读取其扇区信息 将指定文件装入指定内存区,并执行 学会在bochs中 ...

  3. 自己动手写操作系统--搭建保护模式下的运行环境:bochs下安装freedos

    在进行保护模式的运行环境配置前,先看了了下书上的代码,编译运行结果如下:nasm 3_pmtest1.asm -o pmtest1.bin,可以看到界面出现了红色的 p 字 保护模式环境配置 1:在网 ...

  4. 操作系统引导--从实模式到保护模式

    从开始到保护--系统开机引导 ------没有一个文档能写的通俗易懂,我希望写出来. 开机引导和实模式: 两个星期加上假期吐血整理,所述为计算机的开机引导,其中包括一系列计算机内存设置等等,由于没有老 ...

  5. 【OS学习笔记】二十六 保护模式八:任务门---任务切换

    上一篇文章学习了:保护模式七:调用门与依从的代码段----特权级保护 主要学习了以下内容: 描述符特权级(目标对象的特权级)DPL 描述符特权级(目标对象的特权级)DPL 当前特权级CPL 低特权级的 ...

  6. 从零开始操作系统------探析保护模式

    本文基于郑纲的<操作系统还原>,仅为个人学习笔记,前期的虚拟机配置等不再详细记录,其中不理解或者出错的地方还望提出意见! 从零开始操作系统------MBR直操硬盘.内核加载器 为什么有保 ...

  7. 【OS学习笔记】三十一 保护模式九:页目录、页表和页三者的关系详解

    上一篇文章学习了:保护模式九:段页式内存管理机制概述 本篇文章接着学习以下内容: 页目录概念 页表概念 页目录.页表与页之间的关系 虚拟地址(线性地址)到物理地址的具体变换过程. 1.页目录.页表和页 ...

  8. 【OS学习笔记】十九 保护模式六:保户模式下操作系统内核如何加载用户程序并运行

    上一篇文章学习了保户模式下如何进行内存保护 与 别名段的意义与作用:点击链接查看上一篇文章:点击链接 本文接着学习,在保护模式下,内核是如何加载用户程序并运行的.其实这与在实模式下很像,只不过现在保护 ...

  9. 【OS学习笔记】十五 保护模式三:保护模式下的内存访问机制

    上一篇文章学习了段描述符与段描述符各个标志位的含义:段描述符 本篇文章学习如何进入保护模式,并学习如何在保护模式下进行内存访问. 1.如何进入保护模式 假设我们已经用汇编语言将段描述符安装到GDT中( ...

  10. 保护模式超强的寻址功能:天空任鸟飞

    X86架构下,cpu 的运行模式分两种,一种是实模式,像早期Dos那种黑底白字的命令行操作界面,可以说是实模式最好表现形式,在实模式下也只能产生这种冰冷,呆板,机械的用户体验.后来Intel的CPU进 ...

最新文章

  1. 【转】NG:垂枝桦基因组图谱构建(2+3组装)及重测序分析
  2. Tomcat灵活配置多项目,多端口,多域名,多虚拟目录
  3. ASP.NET Ajax – History Support 續
  4. SAP Spartacus delivery mode continue button单元测试失败原因分析
  5. puppeteer( Nodejs 版 selenium )快速入门
  6. 机器学习——决策树的实现
  7. swift之Mac中NSView视图里的截图【ScrollView中的内容截图】
  8. NYOJ--448--寻找最大数
  9. perl引用中的闭包closure
  10. 安全管理:为软件供应链部署零信任方法
  11. 公众号H5运营如何激发用户的打开H5商城欲望?
  12. 光环PMP 项目资源管理、项目相关方管理
  13. 联想Y7000安装显卡驱动
  14. i.MX Yocto Project User‘s Guide
  15. 解决:idea运行scala程序,报错:Error:scalac: bad option: -make:transitive
  16. 158. 精读《Typescript 4》
  17. 计算机维修的入门知识
  18. Oracle同义词总结
  19. 微信小程序给电商行业创业的新曙光
  20. const指针的一些总结

热门文章

  1. IDC最新数据库报告:阿里云份额跃居第一 首次超越传统数据库
  2. 甘肃单招计算机应用基础知识,甘肃单招考试真题试卷
  3. MACD经典战法,讲明趋势MACD的奥义
  4. 设计模式之抽象工厂(C++)
  5. 理解Mathf.Lerp
  6. Eggjs 跨域配置
  7. Java连接SMB服务器异常
  8. 华胜天成收购摩卡软件 IT运维市场洗牌在即
  9. Ubuntu 16.04 + Kinect for Xbox one(v2)驱动安装
  10. Synchronized 和 Lock 的区别和使用场景