我去,又又又被内存坑了!

发布日期:2022-06-18 17:10    点击次数:198


我去,又又又被内存坑了!

公共好,我是你们的老挚友轩辕。

点进这篇著述的挚友,恭喜你们,又要成绩新常识了~

这又是一篇相配硬核的技巧文,漠视互助一瓶怡宝或养分快线食用,后果更好哦。

好多小伙伴在学操作系统的时间,学习到内存管制的部分时,都会战役到分段内存管制、分页内存管制。

但好多人学完以后稀里糊涂:

到底面前用的是分段如故分页?

段寄存器这个东西面前还在用吗?

为什么在讲到诬捏地址翻译的时间,好像跟段又没联系系了呢?

之统共有这个问题,是因为好多同学看的教程好多都是偏表面的或者是落后的,根柢不给你讲当代操作系统中实践的情况(对于这极少我依然吐槽好屡次了)。

今天轩辕就带公共把内存管制的这些疑问一次性弄明晰,分段如故分页,别再傻傻分不明晰了!

Let's go!

在运转之前,咱们如故先来简便温习一下,操作系统书上讲到的Intel x86 CPU架构下的分段式内存管制和分页式内存管制。

分段式内存管制

早在16位的8086期间,CPU为了能寻址逾越16位地址能示意的最大空间(64KB),引入了段寄存器。

通过将内存空间永别为些许个段,然后罗致段基地址+段内偏移的方式探询内存,这么能探询1MB的内存空间了!

当时间,段寄存器有4个,分别指向不同的段。

cs: 代码段 ds: 数据段 ss: 栈段 es:膨胀段

在阿谁时间,段寄存器中存放的是段基地址,扎眼,是一个地址。

在通过ip寄存器读取教唆的时间,实践上是cs:ip,通过sp寄存器探询栈的时间,实践上是ss:sp。

我看到集结上好多著述先容分段式内存或者先容段寄存器的时间就留步于此了,而事实上,参加32位期间后,情况依然发生了天崩地裂的变化,只讲上头这一部老实容实践上会误导好多人。

变化1:

在32位期间,段寄存器又增多了两个:fs、gs,这两个段寄存器有突出用途。

变化2:

段寄存器内部存放的不再是段基地址,而是一个叫段聘请子的东西。扎眼,扎眼,一切的变化都从这里运转。

段寄存器是16位的宽度,蓝本这16位是个物理内存地址,但面前,它是这么一个结构:

实践上,面前的段寄存器中存放的是一个号码,什么号码呢?是一个表格中表项的号码,这个表,有可能是全局描写符表GDT,也有可能是局部描写符表LDT。

那到底是哪个表?是由段聘请子从低到高的第三位来决定的,要是这一位是0,则是GDT,不然等于LDT。

那这两个表又是啥,表内部装的又是什么,何如来寻址呢?

这两个表的表项叫做段描写符,描写了一个内存段的信息,比如段的基地址、最大长度、探询属性等等一系列信息,它长这个样式:

CPU中单独添置了两个寄存器,用来指向这两个表,分别是gdtr和ldtr。

在寻址的时间,CPU率先阐明段寄存器中的号码,通过gdtr或ldtr来到GDT/LDT中取出对应的段描写符,然后再取出这个段的基地址,临了再联接段内的偏移,完成内存寻址。

也等于说,在16位模式下,段寄存器中径直等于一个地址,额外于一个指针,而到了32位下,则变成了一个句柄,或者说二级指针了。

分页式内存管制

比较分段式内存管制,可能公共对分页式内存管制要老练的多。

操作系统将内存空间按照“页”为单元永别了好多页面,这个页的大小默许是4KB(天然不错改的),各程度领有诬捏的完好的地址空间,程度中使用到的页面会映射到真实的物理内存上,手脚中使用的地址是诬捏地址,CPU在运行时自动将其翻译成真实的物理地址。

既然要翻译,那就得有场地纪录诬捏地址和物理地址的映射关系,唯一阐明这个关系,才智完成翻译。

这个映射关系,是通过页表来完成的。

页表是用来纪录诬捏内存页面和物理内存页面之间的映射关系的,每一个页表项纪录一个页面的映射关系。但程度的地址空间很大,这么算下来需要的页表项的数目也会相配多。而实践上程度地址空间中好多页面都莫得着实使用,也就莫得映射关系,这么是一种奢侈。

为了惩办这个问题,CPU引入了多级页表的机制,在32位下一般是2级页表,像底下这么:

将诬捏地址永别了三段:页目次索引、页表索引、页内偏移。

线程切换时,要是同期发生了程度切换,CPU中的CR3寄存器将会加载现时景度的页目次地址。

在寻址的时间,通过CR3,一级一级按表索页,最终找到对应的物理内存页面,再联接页面内的偏移值,终了最终的内存寻址。

当代操作系统实践情况

学完毕这两种内存管制方式,好多人就要懵了:

面前操作系统到底用的哪种方式?好像是分页,但为什么段寄存器好像如故有,到底是何如一趟事?

先说论断,谜底等于:分段+分页相联接的内存管制方式

率先要明确一个前提,这极少相配相配热切:不论是分段如故分页,好吊妞国产欧美日韩免费观看这都是x86架构CPU的内存管制机制,这俩是同期存在的(保护模式下),并不是让操作系统二选一!

既然是同期存在的,那为什么面前将内存地址翻译时,都是讲分页,而很少谈到分段呢?

这一切的一切,都是因为一个原因:操作系统通过巧妙的建造,‘屏蔽’了段的存在。

操作系统何如做到这极少的,接下来咱们就来分析一下,透澈弄明晰背后的猫腻!

段寄存器

让咱们从段寄存器登程,在Win7 32位系统上,使用调试器(我用的WinDbg)粗略调试一个手脚,确切,粗略,记事本、浏览器、Word,你看上谁就调试谁。

在中断的高下文中看一下,手脚在推论时,段寄存器内部到底装了啥?

来看下几个主要的段寄存器的内容:

cs: 001b ds: 0023 ss: 0023 es: 0023

PS: 可能不同版块的Windows上头的规定不通常,但这不热切,不影响咱们分析问题。

唯一0x001b和0x0023两个值,前边咱们说了,这不是一个地址,而是一个段聘请子,按照段聘请子的体式张开来看一下这两个值指向的是哪个段描写符:

十六进制:001b  二进制:0000000000011 0 11  段序号:3  表类型:GDT  特权级:Ring3 
十六进制:0023  二进制:0000000000100 0 11  段序号:4  表类型:GDT  特权级:Ring3 

也等于说,cs段指向的是GDT中的第3个表项,其他三个寄存器指向的是GDT中的第4个表项。

接下来,咱们来看一下这个玄机的GDT内部的内容到底是什么?好多人学了内存管制,可能还从来没看过真实的GDT内部到底是什么数据吧。

GDT是位于操作系统内核地址空间中的,在Windows上有两种检察方式,一种是通过Windbg,一种是通过一些ARK器具,我这里聘请使用PChunter这个神器进行检察。

前边提到过,GDT中的表项是段描写符,这是一个比较复杂的数据体式,好在,这个神器对段描写符进行了领略,使用表格字段的方式进行了展示,让咱们看起来放松多了。

谎话未几说了,来看一下这个玄机的GDT吧:

扎眼看第3个表项和第4个表项哦,望望它们的基地址,都是0x00000000。

再看它们的规模值,都是0x000FFFFF,扎眼看这个规模的单元,不是字节,而是Page——页,把这个值乘以页面的大小4KB,等于0xFFFFF000。也就说这个段的上限到了0xFFFFF000这个页面,再把这一个页面的大小加进去,等于0xFFFFFFFF了!

是以,重心来了!看到了吗,GDT中的第3个和第4个表项所描写的这两个段,它们的基地址都是0x00000000,统共这个词段的大小都是0xFFFFFFFF,这意味着什么?这意味着统共这个词程度的地址空间实践上等于一个段!

也等于说:程度的代码段、数据段、栈段、膨胀段这四个段沿路重合了,况且是统共这个词程度地址空间打算4GB成为了一个段。

提及来是分段,实践上等于没分了,再加上段的基地址沿路是0,那进行地址翻译的时间,有莫得段都没什么区别了。

纪念一句话:操作系统这么分段,实践上是额外于把段给架空了!

以上是Windows的情况,咱们再来看一下Linux情况呢。

使用GDB粗略调试一个ELF32的可推论文献,使用info r高歌检察一下寄存器情况:

段寄存器有0x23和0x2b两种情况:

十六进制:0023 二进制:0000000000100 0 11 段序号:4 表类型:GDT 特权级:Ring3 
十六进制:002B 二进制:0000000000101 0 11 段序号:5 表类型:GDT 特权级:Ring3 

Linux下我莫得找到不错径直用什么高歌或者器具检察GDT的方式(要是你清爽铭记一定告诉我哦),于是去源代码中寻找谜底:

看到了吗,这两项所描写的段和Windows通常,基地址为0,大小为4GB。

Windows和Linux都聘请了通过这种方式架空了CPU的分段内存管制机制。

但需要施展一下的时,诚然两个操作系统都是这种情况,但并不料味着段机制透澈没用到,CPU的任务管制TSS如故需要用到,这极少公共清爽就行了。

64位情况

看到操作系统们都不待见这个分段式内存管制,Intel似乎也感受到了这玩意确乎很鸡肋,于是到了64位平台,透澈把段寄存器给打入了冷宫!

在Intel的教唆手册中,对于64位下的段寄存器是这么描写的:

不管你的段寄存器中指向的段基址是什么内容,都会被当成0来对待。

这一下,分段内存管制,透澈凉凉了···

纪念

好了,最自后纪念一下。

不论是分段如故分页,这是CPU自己的机制,操作系统在管制内存时绕不外去,但通过巧妙的分段内存联想,额外于把分段的见地给屏蔽了,由此酿成了咱们正常在挑剔诬捏地址翻译时,健忘了段的存在,但不代表它确切不存在。

CPU硬件层面的责任必须是联接分段+分页的内存管制机制,操作系统是软件绕不外去,是以选定了上头的方式应答CPU了事。

从16位到32位再到如今大量的64位,不同的期间,分段管制的实践情况都不通常,公共在学习操作系统的时间一定不要死记硬背,而要联接子际情况哦。

面前分段和分页,你弄明晰了吗?

以为有成绩的话,帮手给轩辕共享转发维持一下啊~

 






Powered by 丰满多毛的大隂户毛茸茸 @2013-2022 RSS地图 HTML地图

栏目分类

热点资讯

相关资讯