以一段汇编代码介绍操作系统进入保护模式:
编译:▹ nasm pmtest1.asm -o pmtest1.bin
参数:软盘映像a.img和Bochs的配置文件bochsrc
写入:将生成的二进制写入软盘映像,▹ dd if=pmtest1.bin of=a.img bs=512 count=1 conv=notrunc
运行:Bochs (补图)

1 ; ==========================================
2 ; pmtest1.asm
3 ; 编译方法:nasm pmtest1.asm -o pmtest1.bin
4 ; ==========================================
5
6 %include ”pm.inc” ; 常量, 宏, 以及一些说明
7
8 org 07c00h
9 jmp LABEL_BEGIN
10
11 [ SECTION .gdt]
12 ; GDT
13 ; 段基址, 段界限 , 属性
14 LABEL_GDT: Descriptor 0, 0, 0 ; 空描述符
15 LABEL_DESC_CODE32: Descriptor 0, SegCode32Len - 1, DA_C + DA_32; 非一致代码段
16 LABEL_DESC_VIDEO: Descriptor 0B8000h, 0ffffh, DA_DRW ; 显存首地址
17 ; GDT 结束
18
19 GdtLen equ $ - LABEL_GDT ; GDT长度
20 GdtPtr dw GdtLen - 1 ; GDT界限
21 dd 0 ; GDT基地址
22
23 ; GDT 选择子
24 SelectorCode32 equ LABEL_DESC_CODE32 - LABEL_GDT
25 SelectorVideo equ LABEL_DESC_VIDEO - LABEL_GDT
26 ; END of [SECTION .gdt]
27
28 [ SECTION .s16]
29 [ BITS 16]
30 LABEL_BEGIN:
31 mov ax, cs
32 mov ds, ax
33 mov es, ax
34 mov ss, ax
35 mov sp, 0100h
36
37 ; 初始化 32 位代码段描述符
38 xor eax, eax
39 mov ax, cs
40 shl eax, 4
41 add eax, LABEL_SEG_CODE32
42 mov word [LABEL_DESC_CODE32 + 2], ax
43 shr eax, 16
44 mov byte [LABEL_DESC_CODE32 + 4], al
45 mov byte [LABEL_DESC_CODE32 + 7], ah
46
47 ; 为加载GDTR 作准备
48 xor eax, eax
49 mov ax, ds
50 shl eax, 4
51 add eax, LABEL_GDT ; eax <- gdt 基地址
52 mov dword [GdtPtr + 2], eax ; [GdtPtr + 2] <- gdt 基地址
53
54 ; 加载 GDTR
55 lgdt [GdtPtr]
56
57 ; 关中断
58 cli
59
60 ; 打开地址线A20
61 in al, 92h
62 or al, 00000010b
63 out 92h, al
64
65 ; 准备切换到保护模式
66 mov eax, cr0
67 or eax, 1
68 mov cr0, eax
69
70 ; 真正进入保护模式
71 jmp dword SelectorCode32:0 ; 执行这一句会把SelectorCode32 装入cs,
72 ; 并跳转到Code32Selector:0 处
73 ; END of [SECTION .s16]
74
75
76 [ SECTION .s32]; 32 位代码段. 由实模式跳入.
77 [ BITS 32]
78
79 LABEL_SEG_CODE32:
80 mov ax, SelectorVideo
81 mov gs, ax ; 视频段选择子(目的)
82
83 mov edi, (80 * 11 + 79) * 2 ; 屏幕第11行, 第79列。
84 mov ah, 0Ch ; 0000:黑底 1100:红字
85 mov al, 'P'
86 mov [gs:edi], ax;
87
88 ; 到此停止
89 jmp $
90
91 SegCode32Len equ $ - LABEL_SEG_CODE32
92 ; END of [SECTION .s32]

说明:这段代码将实现由实模式到保护模式的转换。执行▹ nasm pmtest1.asm -o pmtest1.bin 生成纯二进制文件。程序中定义的section没有实质的作用。

代码解读:
[SECTION .gdt]:Descriptor是在pm.inc中定义的宏(如下所示),表示的不是一段代码,而是一个数据结构,它的大小是8字节。

251 ; 描述符
252 ; usage: Descriptor Base, Limit, Attr
253 ; Base: dd
254 ; Limit: dd (low 20 bits available)
255 ; Attr: dw (lower 4 bits of higher byte are always 0)
256 %macro Descriptor 3
258 dw %1 & 0FFFFh ; 段基址1
257 dw %2 & 0FFFFh ; 段界限1
259 db (%1>>16) & 0FFh ; 段基址2
260 dw ((%2>>8) & 0F00h) | (%3 & 0F0FFh) ; 属性1+段界限2+属性2
261 db (%1>>24) & 0FFh ; 段基址3
262 %endmacro; 共 8 字节

在段[SECTION.gdt]中并列有3个Descriptor,是个结构数组,这个数组的名字叫做GDT。GdtLen是GDT的长度,GdtPtr也是个小的数据结构,它有6字节,前2字节是GDT的界限,后4字节是GDT的基地址。另外还定义了两个形如SelectorXXXX的常量。
[ SECTION .s16]: 再往下到了一个代码段,[BITS 16]明确地指明了它是一个16位代码段。你会发现,这段程序修改了一些GDT中的值,然后执行了一些不常见的指令,最后通过jmp指令实现一个跳转(第71行)。正如代码注释中所说的,这一句将“真正进入保护模式”。[ SECTION .s32]: 实际上,它将跳转到第三个section,即[SECTION .s32]中,这个段是32位的,执行最后一小段代码。这段代码看上去是往某个地址处写入了2字节,然后就进入了无限循环。

OrangeS一个操作系统的实现--保护模式相关推荐

  1. redis踩坑:redis哨兵开启了保护模式导致主从切换不同步

    故障表现 哨兵只存在两个的时候,当哨兵模式的redis主节点挂掉以后,业务组件不能切换到新主节点 故障原因 redis哨兵依旧认为旧主为主节点,没有触发failover 故障原因定位 哨兵集群部署方式 ...

  2. Bochs源码分析 - 20: 开启保护模式

    前言 在邓志老师的<x86/x64体系探索及编程>中讲述了开启保护模式的顺序,我尝试着翻阅intel手册,但很遗憾似乎自己没有找到对此的描述(应该是有的,但是自己没找到,日后找到了会补充上 ...

  3. 特权级转移 之 保护模式下数据段特权级保护依据

    提炼: 1 对于数据段 ,处理器进行特权级检查的时机 就是为段寄存器赋值的那一个时刻 在保护模式下 当处理器对段寄存器进行赋值的时候,处理器就会使用规则进行特权级的检查.如: mov ax, Data ...

  4. 我是如何学习写一个操作系统(三):操作系统的启动之保护模式

    前言 上一篇其实已经说完了boot的大致工作,但是Linux在最后进入操作系统之前还有一些操作,比如进入保护模式.在我自己的FragileOS里进入保护模式是在引导程序结束后完成的. 实模式到保护模式 ...

  5. 《Orange’s 一个操作系统的实现》3.保护模式7-特权级转移(通过调用门转移目标段-无特权级转换)...

    在上次的代码基础上,添加一个代码段作为通过调用门转移的目标段.了解一下调用的工作方法,代码分析如下: <<红色标识部分为新增代码>> ; =================== ...

  6. 《Orange’s 一个操作系统的实现》3.保护模式4----LDT(Local Descriptor Table)

    还是在原有代码基础上进行修改,加入LDT的使用,代码分析如下(红色部分为新增代码): 本程序是在原有完成大内存读写测试完成后,调用局部任务显示字符L ; ======================= ...

  7. 《Orange’s 一个操作系统的实现》3.保护模式3----DOS加载.EXE过程

    在<<Orange's 一个操作系统的实现>>一书中有时使用了org 0100h,为何是0100h?因为书中的例子是为了突破引导扇区512字节的限制, 而将asm文件编译为.c ...

  8. 跳转到保护模式并显示一个LOGO

    注:本程序为原创,若发现bug,万望指出,若有问题,欢迎交流,转载请指明出处.若能有助于一二访客,幸甚. 以下为结果截图,显示的LOGO为小篆字体的欢迎 baby os 加载完成...几个字. 保护模 ...

  9. 一个进入保护模式加载引导程序的BOOTLOADER

    ; haribote-ipl ; TAB=4 CYLS    EQU        10                ; 偳偙傑偱撉傒崬傓偐 ORG        0x7c00           ...

最新文章

  1. 怎样设定手机或平板让它更安全?
  2. Python 技术篇-通过进程名获取进程pid实例演示,使用psutil库获取进程id
  3. 利用SIFt特征点和RANSAC方法进行物体识别(利用openCV和vs2010实现)
  4. JAVA通信编程(五)——串口通讯的补充说明
  5. 【java】用javaSE来实现对mysql数据库的增删改查
  6. mysql 省份名排序,mysql省份表,含行政区划代码、省份名和省份全拼
  7. POI导出excel加水印
  8. matlab检验数据异方差,求教!怀特异方差检验方法在matlab中的实现,以及广义最小平方法...
  9. 如何清理废弃pv和其对应的文件夹
  10. ADF7901BRUZ ASK/FSK发射器 ISM频段
  11. 【干货】如何有效地提问
  12. 当系统logoff或shutdown时,让应用程序正常关闭
  13. Photoshop中的填充功能
  14. 高通平台开发系列讲解(网络篇)SFE软加速简介
  15. 3D游戏建模需要学会哪些软件?想入行游戏建模的你都学习了吗?
  16. 悄悄分享 60 个相见恨晚的神器工具
  17. codecombat极客战记地牢蓝色练习关通关代码
  18. 2015年第六届蓝桥杯C/C++B组省赛题目二、星系炸弹答案
  19. 网络知识大集合(最详细)与网络通信过程
  20. python 13位时间戳

热门文章

  1. 目标检测数据集:潜艇(1)
  2. 齐鲁师范学院计算机科学与技术分数线,2019齐鲁师范学院各专业录取分数线汇总情况公布 - 智优学好网...
  3. 高德地图实现路线规划+轨迹回放(显示车牌)
  4. (FLANN论文)fast approximate nearest neighbors with automatic algorithm configuration——中英对照翻译
  5. python常用文本处理方法小结
  6. 对比度易读性阈值研究_对比度研究:字体大小,对比度和可访问性
  7. Java - JDK 安装、环境配置
  8. Acer商祺x4610安装及使用
  9. Chrome - Postman interceptor 和Postman bridge安装及启动
  10. win8 桌面显示计算机图标怎么删除,win8系统桌面图标显示快捷方式箭头怎么删除...