0 00:00:00,000 --> 00:00:06,480 1 00:00:06,520 --> 00:00:08,400 前面我给大家介绍了一下 2 00:00:08,440 --> 00:00:12,520 我们在完成实验中所要用到一些工具 3 00:00:12,560 --> 00:00:15,680 简单介绍了一下 接下来我们看看 4 00:00:15,720 --> 00:00:17,760 对X86-32一个基本理解 5 00:00:17,800 --> 00:00:22,080 这里面讲解在Lab0里面讲解应该说很简单一个介绍 6 00:00:22,120 --> 00:00:24,360 随着实验的逐步进展 7 00:00:24,400 --> 00:00:27,600 我们会对硬件有更深入的介绍 8 00:00:27,640 --> 00:00:31,360 特别是内存管理 特别是进程调度等方面 9 00:00:31,400 --> 00:00:34,600 还有中断处理 会有更详细的介绍 10 00:00:34,640 --> 00:00:36,520 来看看X8632怎么回事 11 00:00:36,560 --> 00:00:40,240 第一个就是X86 我们说X86是个简称 12 00:00:40,280 --> 00:00:43,360 其实这里面指的是什么 80386这种机器 13 00:00:43,400 --> 00:00:47,000 这种机器是因特尔32位的CPU 14 00:00:47,040 --> 00:00:49,120 早期使用的很广泛 15 00:00:49,160 --> 00:00:52,320 特别是在上个世纪90年代初 16 00:00:52,360 --> 00:00:55,320 这个机器是很普遍使用的机器 17 00:00:55,360 --> 00:00:57,960 它有四种运行模式 18 00:00:58,000 --> 00:01:02,640 在我们ucore操作系统实验中涉及到两种 19 00:01:02,680 --> 00:01:05,200 一种实模式 一种是保护模式 20 00:01:05,240 --> 00:01:08,240 实模式等于它只有16位的寻址空间 21 00:01:08,280 --> 00:01:12,360 且没有保护机制 但是保护模式就不一样了 22 00:01:12,400 --> 00:01:14,320 保护模式有32位的寻址空间 23 00:01:14,360 --> 00:01:17,480 且有很强大保护机制来确保 24 00:01:17,520 --> 00:01:18,560 操作系统的安全 25 00:01:18,600 --> 00:01:21,640 以及跑的各个程序之间的安全性 26 00:01:21,680 --> 00:01:23,400 就是用保护模式来实现 27 00:01:23,440 --> 00:01:26,120 所以说在这里面我们需要理解 28 00:01:26,160 --> 00:01:27,960 什么是实模式 什么是保护模式 29 00:01:28,000 --> 00:01:30,360 实模式其实就是80386机器为了 30 00:01:30,440 --> 00:01:33,400 兼容早期的8086十六位机器 31 00:01:33,440 --> 00:01:37,080 做的一种模式 这种模式机器加电之后 32 00:01:37,120 --> 00:01:39,280 一启动就处于实模式运行状态 33 00:01:39,320 --> 00:01:42,360 在这个时候它的寻址空间不超过1M 34 00:01:42,400 --> 00:01:46,280 且无法发挥80386 4G内存管理机制 35 00:01:46,320 --> 00:01:47,960 那么早期的Microsoft 36 00:01:48,000 --> 00:01:53,160 微软的dos操作系统就运行实模式环境中 37 00:01:53,200 --> 00:01:55,560 这也是一个早期很早的OS 38 00:01:55,600 --> 00:01:57,680 也是微软最早一个OS 39 00:01:57,720 --> 00:02:01,720 当然它这个完全不能够发挥我们30位机器特点 40 00:02:01,760 --> 00:02:05,160 所以我们希望我们运行在保护模式 41 00:02:05,200 --> 00:02:07,800 在需要一个设置Lab1就会碰到 42 00:02:07,840 --> 00:02:11,240 你怎么从一开始处于实模式切换到保护模式 43 00:02:11,280 --> 00:02:12,680 一旦有了保护模式 44 00:02:12,720 --> 00:02:15,000 第一个它的寻址空间发生了变化 45 00:02:15,040 --> 00:02:19,720 它从16位或者说1M空间变成了32位寻址空间 46 00:02:19,760 --> 00:02:22,000 有4GB的寻址空间 这是一个 47 00:02:22,040 --> 00:02:25,040 第二它提供所谓分页和分段机制 48 00:02:25,080 --> 00:02:31,000 这两种机制能够让不同软件放在不同的特权级 49 00:02:31,040 --> 00:02:34,040 访问不同空间 且相互之间是隔离的 50 00:02:34,080 --> 00:02:36,160 这种不同的机制就可以使得 51 00:02:36,200 --> 00:02:38,920 我们应用程序可以运行在较低的级别 52 00:02:38,960 --> 00:02:41,640 它限制在运行在一个有限的空间里面 53 00:02:41,680 --> 00:02:45,240 不会破坏操作系统 不会访问那些特权指令 54 00:02:45,280 --> 00:02:48,440 那这就是我们保护模式提供一种功能 55 00:02:48,480 --> 00:02:51,960 我们ucoreos是充分利用了保护模式的特点 56 00:02:52,000 --> 00:02:56,680 完成了一个OS很重要的内存管理 57 00:02:56,720 --> 00:02:58,920 还有特权管理的机制 58 00:02:58,960 --> 00:03:00,960 这里面有一个地址问题 59 00:03:01,000 --> 00:03:03,800 好象大家听地址很简单 60 00:03:03,840 --> 00:03:06,160 地址就是类似于我们每一个同学 61 00:03:06,200 --> 00:03:07,960 家里面都有一个自己地址 62 00:03:08,000 --> 00:03:09,680 这也是地址 家庭地址 63 00:03:09,720 --> 00:03:14,160 我们说对于80386机器而 64 00:03:14,200 --> 00:03:16,440 它对每一个类型单元都有一个编制 65 00:03:16,480 --> 00:03:19,320 当然这个地址实际上我们访问 66 00:03:19,360 --> 00:03:20,640 内存空间的一个索引 67 00:03:20,680 --> 00:03:23,400 既然80386是一个32位的处理器 68 00:03:23,440 --> 00:03:26,680 所以说它寻址空间是4G空间了 69 00:03:26,720 --> 00:03:30,160 这是一个 第二个我们说在计算机里面 70 00:03:30,200 --> 00:03:33,160 它有很多不同寻址方式 71 00:03:33,200 --> 00:03:35,560 首先我们硬件 我们CPU的物理硬件 72 00:03:35,600 --> 00:03:37,320 它有一个物理内存 73 00:03:37,360 --> 00:03:41,080 物理内存是处理器发出一个地址 74 00:03:41,120 --> 00:03:43,680 寻址一个地址请求 这地址请求发哪呢 75 00:03:43,720 --> 00:03:46,560 发到总线上用于访问计算机系统中的所有内存 76 00:03:46,600 --> 00:03:48,320 和外设的最终地址 77 00:03:48,360 --> 00:03:51,360 我们都知道大家如果拆开机器可以看到内存条 78 00:03:51,400 --> 00:03:55,120 那么内存条里面的地址就是所谓物理地址 79 00:03:55,160 --> 00:03:56,120 我们访问某一个物理地址 80 00:03:56,160 --> 00:04:00,080 是把内存某一个内存单元内容给读出来 81 00:04:00,120 --> 00:04:04,040 这是物理地址 第二个叫线性地址 82 00:04:04,080 --> 00:04:09,440 这个是80386机器里面引用的一种地址 83 00:04:09,480 --> 00:04:11,520 线性地址什么意思呢 84 00:04:11,560 --> 00:04:14,640 它是说由于我们有了一个所谓的段模式 85 00:04:14,680 --> 00:04:16,760 让某一个应用程序 86 00:04:16,800 --> 00:04:19,600 能够有一个相对独立地址空间 87 00:04:19,640 --> 00:04:21,600 这个应用程序它认为它自己 88 00:04:21,640 --> 00:04:24,880 是独占了计算机系统地址空间 89 00:04:24,920 --> 00:04:27,840 这个地址空间我们把它称之为线性地址空间 90 00:04:27,880 --> 00:04:30,680 当然这个线性地址空间是靠所谓 91 00:04:30,720 --> 00:04:34,480 我们后面说的段模式和页模式 92 00:04:34,520 --> 00:04:36,800 集中在一起来保护来实现的 93 00:04:36,840 --> 00:04:39,240 第三个我们称之为逻辑地址空间 94 00:04:39,280 --> 00:04:42,320 逻辑地址空间是应用程序直接使用地址空间 95 00:04:42,360 --> 00:04:44,960 看起来好象是有点混乱 96 00:04:45,000 --> 00:04:47,480 没关系我们把它简单的 97 00:04:47,520 --> 00:04:51,760 用我们硬件的表述方式来表述一下 98 00:04:51,800 --> 00:04:53,920 如果说80386的段机制启动 99 00:04:53,960 --> 00:04:55,320 页机制没有启动的时候 100 00:04:55,360 --> 00:05:00,960 逻辑地址通过段机制的映射能转变成线性地址 101 00:05:01,000 --> 00:05:02,920 然后线性地址就等同于物理地址 102 00:05:02,960 --> 00:05:06,320 这两个是等价的 那前提是什么呢 103 00:05:06,360 --> 00:05:09,160 段机制启动了 页机制还没有起动了 104 00:05:09,200 --> 00:05:11,000 当然我们讲Lab2的时候 105 00:05:11,040 --> 00:05:13,200 还会对页机制有更深入的讲解 106 00:05:13,240 --> 00:05:15,680 Lab1会对段机制有更深入讲解 107 00:05:15,720 --> 00:05:19,200 第二个是如果段机制和页机制都启动 108 00:05:19,240 --> 00:05:22,320 那么这个时候逻辑地址通过所谓的 109 00:05:22,360 --> 00:05:26,400 段机制它会映射成线性地址 110 00:05:26,440 --> 00:05:29,320 线性地质通过页机制映射成物理地址 111 00:05:29,360 --> 00:05:32,480 从而可以看出来它其实这所谓段机制 112 00:05:32,520 --> 00:05:34,200 和页机制只是一种映射关系 113 00:05:34,240 --> 00:05:37,080 把一个地址从A地址映射到B地址 114 00:05:37,120 --> 00:05:39,440 然后再B地址映射到C地址 115 00:05:39,480 --> 00:05:42,080 然后ABC地址内容是不一样的 116 00:05:42,120 --> 00:05:45,840 当然需要有一个映射关系的实现 117 00:05:45,880 --> 00:05:48,560 那实际上我们的段机和页机制处理的问题 118 00:05:48,600 --> 00:05:50,320 那我们对这个地址空间有一定了解之后 119 00:05:50,360 --> 00:05:53,280 我们再看看访问的寄存器就是CPU 120 00:05:53,320 --> 00:05:57,440 从内存到CPU CPU有一系列寄存器来存储数据 121 00:05:57,480 --> 00:05:59,720 这个寄存器分为以下几组 122 00:05:59,760 --> 00:06:03,400 一共有8组 我们通常看的最多是通用寄存器 123 00:06:03,440 --> 00:06:06,280 跟段相关的所谓段寄存器 124 00:06:06,320 --> 00:06:12,680 然后和寻址相关有指令指针寄存器就是EIP 125 00:06:12,720 --> 00:06:16,120 还有所谓标志寄存器就是Eflags 126 00:06:16,160 --> 00:06:18,760 还有什么呢 就是控制寄存器 127 00:06:18,800 --> 00:06:19,760 和其它调制寄存器等等 128 00:06:19,800 --> 00:06:24,080 最后两位一般开发应用程序用不到 129 00:06:24,120 --> 00:06:27,320 但是我们开发操作系统的时候需要用到 130 00:06:27,360 --> 00:06:30,320 因为这些特殊的寄存器是用来完成特殊的功能 131 00:06:30,360 --> 00:06:33,600 比如说我们刚才讲到让它进入保护模式 132 00:06:33,640 --> 00:06:37,560 让它启动分页 或者启动分段等等 133 00:06:37,600 --> 00:06:40,360 那都需要涉及一系列的控制寄存器 134 00:06:40,400 --> 00:06:42,560 系统地址寄存器等等 135 00:06:42,600 --> 00:06:45,400 这两类应该说专门是用来给 136 00:06:45,440 --> 00:06:48,400 类似于操作系统这样一些系统软件来使用的 137 00:06:48,440 --> 00:06:51,160 而前面的寄存器你在了解 138 00:06:51,200 --> 00:06:53,280 一般应用程序的时候也会用到 139 00:06:53,320 --> 00:06:55,120 那么我们来看看通用寄存器 140 00:06:55,160 --> 00:06:56,240 通用寄存器包含什么呢 141 00:06:56,280 --> 00:06:58,960 EAX EBX等等一直到ESP 142 00:06:59,000 --> 00:07:02,760 它有不同的功能 EAX主要用于累加 寻址 143 00:07:02,800 --> 00:07:04,320 ECX是用来记数 144 00:07:04,360 --> 00:07:07,640 最后ESP是用来堆栈寻址等等 145 00:07:07,680 --> 00:07:10,720 都是很重要的寄存器在我们应用程序 146 00:07:10,760 --> 00:07:13,720 和操作系统编程里面大量使用 147 00:07:13,760 --> 00:07:15,840 但是在ucore操作系统里面 148 00:07:15,880 --> 00:07:17,480 有一小部分是汇编语言 149 00:07:17,520 --> 00:07:19,240 你需要了解汇编语言含义 150 00:07:19,280 --> 00:07:23,360 你就需要知道这些寄存器有什么样功能和特点 151 00:07:23,400 --> 00:07:26,360 从而可以知道汇编语言到底表示什么意思 152 00:07:26,400 --> 00:07:30,520 当然我们在Lab1里面还会对汇编语言做深入讲解 153 00:07:30,560 --> 00:07:32,000 第二个是段寄存器 154 00:07:32,040 --> 00:07:33,640 段寄存器主要是用来寻址 155 00:07:33,680 --> 00:07:35,840 比如说我们要访问是代码段 156 00:07:35,880 --> 00:07:38,480 数据段还是堆栈段等等 那么这是堆栈段 157 00:07:38,520 --> 00:07:43,840 那么你这个CS的值是代表特定含义 158 00:07:43,880 --> 00:07:46,840 在实模式和保护模下它的含义是不一样 159 00:07:46,880 --> 00:07:49,960 这个也需要注意 接下来是指令寄存器 160 00:07:50,000 --> 00:07:52,760 和相应标志寄存器的介绍 161 00:07:52,800 --> 00:07:55,800 指令寄存器主要是指EIP 162 00:07:55,840 --> 00:08:00,360 当然对于16位CPU8086而言 163 00:08:00,400 --> 00:08:03,160 它是由CS和EIP共同决定地址 164 00:08:03,200 --> 00:08:05,240 那个EIP是低16位 165 00:08:05,280 --> 00:08:07,560 实际上就是IP 8086的IP地址 166 00:08:07,600 --> 00:08:09,360 那么CS和IP合在一起 167 00:08:09,400 --> 00:08:12,440 能够访问一共1M的内存地址空间 168 00:08:12,480 --> 00:08:16,480 但是如果是到了保护模式32位的CS 169 00:08:16,520 --> 00:08:18,480 和EIP就有了新的含义 170 00:08:18,520 --> 00:08:22,080 它们结合在一起来完成对32位地址空间的寻址 171 00:08:22,120 --> 00:08:24,160 在这个时候EIP已经表示了什么 172 00:08:24,200 --> 00:08:26,120 是指令的段内偏移地址 173 00:08:26,160 --> 00:08:28,040 这所谓的EFLAGS 174 00:08:28,080 --> 00:08:29,560 这是标志寄存器 175 00:08:29,600 --> 00:08:30,600 那么标志寄存器很有用 176 00:08:30,640 --> 00:08:33,200 比如说你做个加法是否溢出 177 00:08:33,240 --> 00:08:36,880 那么这些所有标志都是记录在EFLAGS里头 178 00:08:36,920 --> 00:08:38,880 而且还有一些特殊的位 179 00:08:38,920 --> 00:08:42,080 比如说是否允许中断等等 180 00:08:42,120 --> 00:08:44,560 这个都是由EFLAGS寄存器里面的 181 00:08:44,600 --> 00:08:48,800 特定的BIT来表示的 大家需要注意 182 00:08:48,840 --> 00:08:51,320 但是也需要了解是有一些BIT 183 00:08:51,360 --> 00:08:53,560 并不能由应用程序来修改 184 00:08:53,600 --> 00:08:54,920 而只能是用操作系统来修改 185 00:08:54,960 --> 00:08:57,480 这属于运行在特权态的操作系统 186 00:08:57,520 --> 00:09:00,520 才有能力去完成标志位的修改 187 00:09:00,560 --> 00:09:03,320 这是所谓的EFLAGS寄存器