程序员的小天地


  • 首页

  • todo

  • 思考

  • life

  • food

  • OS

  • lua

  • redis

  • Golang

  • C

  • TCP/IP

  • ebpf

  • p4

  • OpenVPN

  • IPSec

  • L2TP

  • DNS

  • distributed

  • web

  • OpenWRT

  • 运维

  • Git

  • 鸟哥的私房菜

  • IT杂谈

  • 投资

  • About Me

  • 友情链接

  • FTP

  • 搜索
close

操作系统基础32-内存管理-分段

时间: 2021-08-24   |   分类: os   cs     |   阅读: 1027 字 ~3分钟

操作系统基础32-内存管理-分段

2020-12-20 03:27·重学IT的老猫

通过前面的学习我们知道,用户的内存视图与实际的物理内存不一样。这同样适用于程序员的内存视图。

事实上,对操作系统和程序员来说,按物理性质来处理内存是不方便的。如果硬件可以提供内存机制,以便将程序员的内存视图映射到实际的物理内存,系统将有更多的自由来管理内存,而程序员将有一个更自然的编程环境。分段提供了这种机制。

分段的基本方法

在分段存储管理方式中,作业的地址空间被划分为若干个段,每个段定义了一组逻辑信息。

每个段都有自己的名字。为了实现简单起见,通常可用一个段号来代替段名,每个段都从0开始编址,并采用一段连续的地址空间。段的长度由相应的逻辑信息组的长度决定,因而各段长度不等。整个作业的地址空间由于是分成多个段,因而是二维的,亦即,其逻辑地址由段号(段名)和段内地址所组成。

操作系统基础32-内存管理-分段

因此,逻辑地址由有序对组成: <段号,偏移>

通常,在编译用户程序时,编译器会根据输入程序来自动构造段。 一个C编译器可能会创建如下段:

  • 代码
  • 全局变量
  • 堆(内存从堆上分配)
  • 每个线程使用的栈
  • 标准的C库

在编译时链接的库可能分配不同的段。加载程序会装入所有这些段,并为它们分配段号。

分段硬件

虽然用户现在能够通过二维地址来引用程序内的对象,但是实际物理内存仍然是一维的字节序列。因此,我们应定义一个实现方式,以便映射用户定义的二维地址到一维物理地址。这个地址是通过段表来实现的。

段表的每个条目都有段基地址和段界限。段基地址包含该段在内存中的开始物理地址,而段界限指定该段的长度。

操作系统基础32-内存管理-分段

分段硬件

段表的使用如上图所示。每个逻辑地址由两部分组成:段号 s 和段偏移 d。

段号用作段表的索引,逻辑地址的偏移d应位于0和段界限之间。如果不是这样,那么会陷入操作系统中(逻辑地址试图访问段的外面)。如果偏移d合法,那么就与基地址相加而得到所需字节的物理内存地址。因此,段表实际上是基址寄存器值和界限寄存器值的对的数组。

操作系统基础32-内存管理-分段

分段的例子

例如,假设如上图分段的例子所示的情况。有5个段,按0~4来编号。各段按如图所示来存储。每个段都在段表中有一个条目,它包括段在物理内存内的开始地址(基地址)和该段的长度(界限)。 如,段2为400字节长,开始于位置4300。因此,对段2字节53的引用映射成位置4300 + 53 = 4353。对段3字节852的引用映射成位置3200(段3基地址)+ 852 = 4052。对段0字节1222的引用会陷入操作系统,这是由于该段仅为1000字节长。

#os# #cs#
操作系统基础33-内存管理-分页
操作系统基础31-连续内存分配

日志
分类
标签
GitHub
© 2009 - 2025
粤ICP备2021068940号-1 粤公网安备44011302003059
0%