x86的内存寻址方式

Linux内存管理与进程寻址详解

一、实模式寻址

在16位的8086时代,CPU为了能寻址超过16位地址能表示的最大空间(因为 8086 的地址线 20 位而数据线 16 位),引入了段寄存器。通过将内存空间划分为若干个段(段寄存器像 ds、cs、ss 这些寄存器用于存放段基址),然后采用段基地址+段内偏移的方式访问内存,这样能访问1MB的内存空间了。

使用这样的寻址方式的好处是所见即所得,程序员指定的地址就是物理地址,物理地址对程序员是可见的。但是,由此也带来两个问题:

  1. 无法支持多任务
  2. 程序的安全性无法得到保证(用户程序可以改写系统空间或者其他用户的程序内容)。

实模式将整个物理内存看成分段的区域,程序代码和数据位于不同区域,系统程序和用户程序没有区别对待,而且每一个指针都是指向"实在"的物理地址。

这样一来,用户程序的一个指针如果指向了系统程序区域或其他用户程序区域,并改变了值,那么对于这个被修改的系统程序或用户程序,其后果就很可能是灾难性的。

为了克服这种低劣的内存管理方式,处理器厂商开发出保护模式:物理内存地址不能直接被程序访问,程序内部的地址(虚拟地址)要由操作系统转化为物理地址去访问,从而保护进程地址空间,程序对此一无所知。

二、保护模式寻址

从IA-32开始,cpu有三种工作方式:实模式,保护模式和虚拟8086模式。只有在刚刚启动的时候是实模式,等操作系统运行起来以后就运行在保护模式。虚拟8086模式是运行在保护模式中的实模式,为了在32位保护模式下执行纯16位程序,它不是一个真正的CPU模式,还属于保护模式。在保护模式下,CPU 有更强的寻址能力。

两者的区别主要体现在段寄存器如CS,DS,ES,SS的解释方式不同——实模式解释为段寄存器,保护模式解释为段选择子。

在实模式(也就是16位模式)情况下,一个地址由段和偏移两部分组成,计算公式为:Segment << 4 + Offset(所以实模式下只能访问1M的内存空间)。CS (代码段寄存器) 和 DS (数据段寄存器) 主要用于存储代码段和数据段的起始地址。

在保护模式下寻址方式还是段基址+偏移地址。但是此时寄存器不再直接存储段的基地址,而是存储段描述符表中的索引即段选择子,如下:

|-----------------------------------|-----|--------|
|              索引号
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

得过且过的勇者y

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值