操作系统真象还原:一些你可能正感到迷惑的问题

2024-05-29 22:04

本文主要是介绍操作系统真象还原:一些你可能正感到迷惑的问题,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

第0章-一些你可能正感到迷惑的问题

这是我看操作系统真象还原这本书的一些记录:

4 软件是如何访问硬件的

硬件在输入输出上大体分为串行和并行,相应的接口也就是串行接口和并行接口。串行硬件通过串行接口与 CPU 通信,反过来也是, CPU 通过串行接口与串行设备数据传输。并行设备的访问类似,只不过是通过并行接口进行的。

访问外部硬件有两个方式:

  1. 将某个外设的内存映射到一定范围的地址空间中, CPU 通过地址总线访问该内存区域时会落到外设的内存中,这种映射让 CPU 访问外设的内存就如同访问主板上的物理内存一样。例如显存:它被映射到主机物理内存上的低端 1MB 的0xB8000~0xBFFFF。CPU 访问这片内存就是访问显存,住这片内存上写字节便是往屏幕上打印内容。
  2. 外设是通过 IO 接口与 CPU 通信的, CPU 访问外设,就是访问 IO 接口,由 IO 接口将信息传递给另一端的外设,也就是说, CPU 从来不知道有这些设备的存在,它只知道自己操作的 IO 接口。

5 应用程序是什么,和操作系统是如何配到一起工作的

编译器提供了一套库函数,库函数中又有封装的系统调用,这样的代码集合称之为运行库。 C 语言的运行库称为 C 运行库,就是所谓的 CRT。

应用程序加上操作系统提供功能才算是完整的程序

7 内存访问为什么要分段

CPU 采用 “段基址+段内偏移地址”的形式访问内存,就需要专门提供段基址寄存器,这些是 cs 、 ds 、es 等

程序分段又是为了将大内存分成可以访问的小段,通过这样变通的方法便能够访问到所有内存了

8 代码中为什么分为代码段、数据段?

首先,程序不是一定要分段才能运行的,分段只是为了使程序更加优美 。

x86 平台的处理器是必须要用分段机制访问内存的,正因为如此,处理器才提供了段寄存器,用来指定待访问的内存段起始地址。

分段是必然的,只是在平坦模型下,硬件段寄存器中指向的内存段为最大的 4GB ,而在多段模式下编程,硬件段寄存器中指向的内存段大小不一 。

对于在代码中的分段,有的是操作系统做的,有的是程序员自己划分的 。 如果是在多段模型下编程 ,我们必然会在源码中定义多个段,然后需要不断地切换段寄存器所指向的段,这样才能访问到不同段中的数据,所以说,在多段模型下的程序分段是程序员人为划分的。如果是在平坦模型下编程,操作系统将整个 4GB 内存都放在同一个段中,我们就不需要来回切换段寄存器所指向的段 。 对于代码中是否要分段,这取决于操作系统是否在平坦模型下

由于处理器支持了具有分页机制的虚拟内存,操作系统也采用了分页模型,因此编译器会将程序按内 容划分成代码段和数据段,如编译器 gcc会把 C 语言写 出的程序划分成代码段、数据段、栈段、 .bss 段、堆等部分 。 这会由操作系统将编译器编译出来的用户程序中的各个段分配到不同的物理内存上 。 对于目前咱们用高级语言编码来说,我们之所以不用关心如何将程序分段,正是由于编译器按平坦模型编译,而程序所依赖的操作系统又采用了虚拟内存管理,即处理器的分页机制。

这就是 Intel 处理器的程序计数器 es: eip能够自动获得下一条指令的原理,即将当前 eip 中的地址加上当前指令机器码的大小便是内存中下一条指令的起始地址 。 即使指令间有空隙或其他非指令的数据,这也仅仅是在物理上将其断开了,依然可以用 jmp指令将非指令部分跳过以保持指令在逻辑上连续

为了让程序内指令接连不断地执行,要把指令全部排在一起,形成一片连续的指令区域,这就是代码段 。 把数据连续地并排在一起存储形成的段落,就称为数据段。

  1. 编译器负责挑选出数据具备的属性,从而根据属性将程序片段分类,比如,划分出了只读属性的代码段和可写属性的数据段。
  2. 操作系统通过设置 GOT 全局描述符表来构建段描述符,在段描述符中指定段的位置、大小及属性(包括 S字段和 TYPE 字段)。也就是说,操作系统认为代码应该是只读的,所以给用来指向代码段的那个段描述符设置了只读的属性,这才是真正给段添加属性的地方。
  3. CPU中的段寄存器提前被操作系统赋予相应的选择子从而确定了指向的段。在执行指令时,会根据该段的属性来判断指令的行为,若有返回则发出异常。

9 物理地址、逻辑地址、有效地址、线性地址、虚拟地址

物理地址就是物理内存真正的地址,相当于内存中每个存储单元的门牌号,具有唯一性。在实模式下,“段基址+段内偏移地址”经过段部件的处理,直接输出的就是物理地址, CPU可以直接用此地址访问内存 。

而在保护模式下,"段基址+段内偏移地址”称为线性地址,不过,此时的段基址已经不再是真正的地址了,而是一个称为选择子的东西 。它本质是个索引,类似于数组下标,通过这个索引便能在 GDT中找到相应的段描述符,在该描述符中记录了该段的起始、大小等信息,这样便得到了段基址。若没有开启地址分页功能, 此线性地址就被当作物理地址来用,可直接访问内存。 若开启了分页功能,此线性地址又多了一个名字,就是虚拟地址

无论在实模式或是保护模式下,段内偏移地址又称为有效地址,也称为逻辑地址,这是程序员可见的地址 。

在这里插入图片描述

11 什么是平坦模式

平坦模型是相对于多段模型来说的,所以说平坦模型指的就是一个段 。

12 寄存器

  1. CS一代码段寄存器( Code Segment Register),其值为代码段的段基值
  2. DS一数据段寄存器( Data Segment Register),其值为数据段的段基值。
  3. ES一附加段寄存器( Extra Segment Register),其值为附加数据段的段基值,称为“附加”是因为此段寄存器用途不像其他 sreg 那样固定,可以额外做他用。
  4. FS一附加段寄存器( Extra Segment Register ),其值为附加数据段的段基值,同上,用途不固定,使用上灵活机动。
  5. GS一附加段寄存器( Extra Segment Register),其值为附加数据段的段基值。
  6. SS一堆枝段寄存器( Stack Segment Register),其值为堆栈段的段值。

在实模式下, CS 、 DS 、 ES 、 SS 中的值为段基址,是具体的物理地址,内存单元的逻辑地址仍为“段基值:段内偏移量”的形式。在保护模式下,装入段寄存器的不再是段地址,而是“段选择子” ( Selector),当然,选择子也是数值,其依然为 16 位宽度。

这篇关于操作系统真象还原:一些你可能正感到迷惑的问题的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1014754

相关文章

springboot循环依赖问题案例代码及解决办法

《springboot循环依赖问题案例代码及解决办法》在SpringBoot中,如果两个或多个Bean之间存在循环依赖(即BeanA依赖BeanB,而BeanB又依赖BeanA),会导致Spring的... 目录1. 什么是循环依赖?2. 循环依赖的场景案例3. 解决循环依赖的常见方法方法 1:使用 @La

SpringBoot启动报错的11个高频问题排查与解决终极指南

《SpringBoot启动报错的11个高频问题排查与解决终极指南》这篇文章主要为大家详细介绍了SpringBoot启动报错的11个高频问题的排查与解决,文中的示例代码讲解详细,感兴趣的小伙伴可以了解一... 目录1. 依赖冲突:NoSuchMethodError 的终极解法2. Bean注入失败:No qu

浅谈mysql的sql_mode可能会限制你的查询

《浅谈mysql的sql_mode可能会限制你的查询》本文主要介绍了浅谈mysql的sql_mode可能会限制你的查询,这个问题主要说明的是,我们写的sql查询语句违背了聚合函数groupby的规则... 目录场景:问题描述原因分析:解决方案:第一种:修改后,只有当前生效,若是mysql服务重启,就会失效;

MySQL新增字段后Java实体未更新的潜在问题与解决方案

《MySQL新增字段后Java实体未更新的潜在问题与解决方案》在Java+MySQL的开发中,我们通常使用ORM框架来映射数据库表与Java对象,但有时候,数据库表结构变更(如新增字段)后,开发人员可... 目录引言1. 问题背景:数据库与 Java 实体不同步1.1 常见场景1.2 示例代码2. 不同操作

如何解决mysql出现Incorrect string value for column ‘表项‘ at row 1错误问题

《如何解决mysql出现Incorrectstringvalueforcolumn‘表项‘atrow1错误问题》:本文主要介绍如何解决mysql出现Incorrectstringv... 目录mysql出现Incorrect string value for column ‘表项‘ at row 1错误报错

如何解决Spring MVC中响应乱码问题

《如何解决SpringMVC中响应乱码问题》:本文主要介绍如何解决SpringMVC中响应乱码问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录Spring MVC最新响应中乱码解决方式以前的解决办法这是比较通用的一种方法总结Spring MVC最新响应中乱码解

pip无法安装osgeo失败的问题解决

《pip无法安装osgeo失败的问题解决》本文主要介绍了pip无法安装osgeo失败的问题解决,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一... 进入官方提供的扩展包下载网站寻找版本适配的whl文件注意:要选择cp(python版本)和你py

解决Java中基于GeoTools的Shapefile读取乱码的问题

《解决Java中基于GeoTools的Shapefile读取乱码的问题》本文主要讨论了在使用Java编程语言进行地理信息数据解析时遇到的Shapefile属性信息乱码问题,以及根据不同的编码设置进行属... 目录前言1、Shapefile属性字段编码的情况:一、Shp文件常见的字符集编码1、System编码

Spring MVC使用视图解析的问题解读

《SpringMVC使用视图解析的问题解读》:本文主要介绍SpringMVC使用视图解析的问题解读,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录Spring MVC使用视图解析1. 会使用视图解析的情况2. 不会使用视图解析的情况总结Spring MVC使用视图

Redis解决缓存击穿问题的两种方法

《Redis解决缓存击穿问题的两种方法》缓存击穿问题也叫热点Key问题,就是⼀个被高并发访问并且缓存重建业务较复杂的key突然失效了,无数的请求访问会在瞬间给数据库带来巨大的冲击,本文给大家介绍了Re... 目录引言解决办法互斥锁(强一致,性能差)逻辑过期(高可用,性能优)设计逻辑过期时间引言缓存击穿:给