x86内存相关(32位)

《程序员的自我修养》中介绍详细
带着相关问题分析:

1>为什么要引入虚拟内存
2>内存分布及各部分详解
3>分页分段机制
4>如何进行地址映射

Q:为什么要有虚拟内存??
A:有了虚拟内存,每个进程都独享一个较大的空间,这样能够用占用内存更大的程序。

虚拟内存分布图

这里写图片描述

128M预留空间:禁止访问
.text(代码段) 
可执行文件加载到内存中的只有数据和指令之分,而指令被存放在.text段中,一般是共享的,编译时确定,只读,不允许修改
.data 
存放在编译阶段(而非运行时)就能确定的数据,可读可写。也就是通常所说的静态存储区,赋了初值的全局变量和赋初值的静态变量存放在这个区域,常量也存放在这个区域
.bss段 
通常用来存放程序中未初始化以及初始化为0的全局/静态变量的一块内存区域,在程序载入时由内核清0
.heap(堆) 
用于存放进程运行时动态分配的内存,可动态扩张或缩减,这块内存由程序员自己管理,通过malloc/new可以申请内存,free/delete用来释放内存,heap的地址从低向高扩展,是不连续的空间
.stack(栈) 
记录函数调用过程相关的维护性信息,栈的地址从高地址向低地址扩展,是连续的内存区域

.bss段的意义探索:

这里写图片描述
使用objdump查看各个段的信息:
这里写图片描述

size为该段大小,VMA虚拟内存空间,LMA加载内存地址,File off在文件中的偏移(编译过程中不分配内存)
注意:
1>.text偏移不是0==>ELF Header(大小是52字节)
2>.bss段没有和下一个段偏移相同==>文件中么有》》》??放哪里了

test.o文件:
-----------
ELF Header-----0x00000000 ==>段表位置,段表描述符数量,大小,ELF文件大小等
.text
.data
.bss
...
.Section table  ==>段表???各个段信息
.systab         ==>符号表  //变量 方法
.rel.test       ==>重定位表
------------

段表:
这里写图片描述

偏移 0XF4==>段表位置

.bss段里数据都是0,所以没有必要在文件中分配位置节省.o文件的大小,但是必须得知道有这么个东东,所以段表就完成了这工作。

提到符号表和重定位表:
.o文件的链接:
合并所有obj文件的段,调整偏移和段长,合并符号表并进行符号解析,分配虚拟内存(链接的核心就是符号重定位)

地址映射

内存管理==>软硬结合:硬件(MMU内存管理单元)+软件(页表等信息)

实模式:物理内存 = 段地址DS左移4位 + IP(逻辑地址)
---
why?:   搜噶!
实模式依然是段式管理,存在着段寄存器和IP寄存器。32位系统的地址总线是20条,但是段寄存器是从X86体系下继承过来的,那么段寄存器的大小是16位,规定每个内存段的起始地址必须是16的倍数,那么一个段的物理内存为2^16=64K。但是20和16明显对比不上。怎么办呢?让我们来看看16的二进制写法,0010 000。也就是低4位全部为0。那么20位的低4为全部为0,剩下的高16位就能够放进去了。所以寻址方式成了这个样子:如果要寻找某个数据的内存,那么要从DS寄存器里找,DS寄存器里放的是高16位,那么得左移4位得到所在段的地址,再加上IP寄存器里的偏移量,最后获得数据的地址,也就是物理地址。

开机时强制进入实模式,1M大小内存 ==> 加载完OS后就进入保护模式。
---

保护模式:增加了两个寄存器 = GDT(全局的段描述符表的地址)+LDT(局部)
保存了内存的起始地址 内存段大小 访问权限
---
段寄存器:(16位) 但是(IP是32位)
15                      1 0
|。。。。。。。。。。|TI| RPL|

低两位:RPL表示权限级别==00内核态 11表示用户态
TI   :0使用GDTR 1使用LDTR
其他13位表示8192个描述符表(系统已经用了12个)

CPU其他重要寄存器:
CR0:最高位叫PG位,0:未开启分页机制,1:开启分页机制
CR2:发生缺页异常的虚拟地址
CR3:页目录的起始地址
CR4:PAE位 物理地址扩展 0:未开启 1:开启

地址映射:
--
GDT[DS>>3].baseadd(基址) + IP(逻辑地址) == 线性地址

如果没有开启页表机制==> 线性地址==物理地址
如果开启页表机制==> 线性地址 == 虚拟地址
32位的虚拟地址分3 份 :  10      +     10     +      12
                    页目录下标1024   页表下标1024   页面上的偏移(4K)
1024*1024*4K==>>4G
得到物理地址

猜你喜欢

转载自blog.csdn.net/m18706819671/article/details/80630765
今日推荐