32位x86处理器

16位处理器
指令中 操作数8/16bit 内存地址 16bit
在这里插入图片描述

32位处理器
兼容16位处理器使用,有自己独立的32位运行模式。在兼容16位处理器使用时使用下图的寻址方式:
在这里插入图片描述
指令中操作数8/16/32bit 内存地址 16/32bit
依据操作尺寸不同 采用不同的寻址方式
在这里插入图片描述
32 位处理器 在实模式下将段界限设置为0xFFFF 以此来限制程序行为与传统实模式一致

mov cx, 0x2000
mov ds, cx    ;将逻辑段地址0x2000加载到ds中

mov eax, 0xFFFF
mov bl, [eax]    ;从偏移量为0xFFFF的地方取一个字节	;ok! you are lucky!
mov bx, [eax]    ;从偏移量为0xFFFF的地方取一个字	;not!! forbidden!!

使用前缀去区分16bit还是32bit编译,这个有点绕人,我被绕进去了,我摆烂了,不提也罢!

存储器的保护

在保护模式下,修改段寄存器需要带入段选择子,此时会校验带入值的合法性,然后从全局描述符表GDT中找到相应的描述符并加载到描述符高速缓存器中,此时会校验描述符的完整性和正确性。

保护方式:

  1. 在全局描述符表GDTR中,有GDT线性基地址和界限值两部分,选择子所选择的描述符必须在边界值以内,也就是索引号 * 8 + 7 <= 边界,如果选择子对应的描述符超出了界限值,处理器会响应一个异常中断13,并且不会改变段寄存器的内容。
  2. 如果要运行代码段那就不能访问到数据段去
  3. 偏移量也不能超出界限
  4. 必须检查指令地址是否有效

段界限的理解

在每一个段描述符中都有如下几个需要注意的部分:
在这里插入图片描述
BASE部分分立开来:组合起来就是段描述符保存的段基址
LIMIT部分分立开来,组合起来就是段描述符保存的段界限
G:Granularity,表示段界限值的单位 0–>1字节 1–>4KB字节
D/B:这个比较复杂后面讲
AVL:avaliable,是否可访问
P:present? 存在? P位是最重要的1位,如果P=0代表这个段描述符不用看了无效是个无效描述符
P=1代表这个段描述符有效(如果P=0其它的所有操作比较都没有意义)
DPL:descriptor privilege level 描述符特权级,用来表示这个描述符的等级,如果访问时段描述符高速缓存器中的CPL大于这个值则无法访问
S:S=0代表这个描述符是系统段描述符,S=1代表这个段描述符是代码段描述符或者数据段描述符
下面我们单独看S=1的情况:
分别是右边黄绿相间的两块。
S=1,type块就会变成绿色块中的部分。type部分由内部的X位继续细分
X:executable,是否可执行,用来指示是代码段还是数据段
X=0 --> 数据段 此时后面的部分变为CRA
C是代表一致性还是非一致性访问
R是代表readable? 是否可读
A是代表accessed 是否以被访问过

X=1 --> 代码段 此时后面的部分变为EWA
E是代表extend 扩展的方向 0是向上扩展 1是向下扩展
W是代表writtable 是否可写 代码段一定是可读的 但不一定是可写的
A是代表accessed 代表是否已访问过


有了以上的铺垫再来说说段界限对访问的约束

段界限用来对访问时给出的IP/EIP偏移值做限制,如果偏移值超出了这个界限,那么就会发生segment fault
根据一下两个因素,段界限应该是不一样的:
因素1:E位,扩展方向
如果E=0 段向上扩展 那么段界限值越大 实际段就越大
如果E=1 段向下扩展 那么段界限值越大 实际段就越小

注意段界限是有最大值的,因为硬件上段界限值是20bit,也就是段最大1M。
所以说E=0情况下 段最大不能超过1M 段界限值不能超过1M-1(因为段界限值是从0开始的)

因素2:G位,段粒度
如果G=0 粒度为1字节 那么段大小的计算应该是 段界限值1 + 1 (为什么+1? 因为段大小等于段界限值+1 段界限值为0时段大小为1 一个单位!!! )
如果G=1 粒度为4KB 那么段大小的计算应该是 段界限值
4KB + 0xFFF + 1 (为什么+0xFFF? 因为段界限值给出0时 根据这个公式 算出段大小才能是0x1000 一个单位!!!)

也就是说公式必须要保证段界限值为0时 段大小 == 一个单位的段界限值(1byte/4kb)


再来说说E=1的情况,单独拎出了,这个确实比较难以理解。
如果E=1 段向下扩展 那么段界限值越大 实际段就越小。
此时
段界限是指栈指针所不允许的最小值 理解这句话就理解了!
假设栈设为最大 初始化时栈段寄存器SS在某个地址上,栈指针SP=SS-1
因为栈是向下生长,栈指针此时在栈底的上一个位置。
段界限此时约束栈的界限
SP越小 SP=SP-2(不断压栈),越靠近栈顶(栈顶现在被段界限所约束),SP有个最小值,如果SP比这个最小值还小,那就是说SP超出了栈界限。发出segment fault
所以说段界限是指栈指针所不允许的最小值

对于一个栈段,他的(E)SP的最大值是0xFFFF(0xFFFFFFFF)( 你也可以设置在红线那里!这是你自己的事情!不用上面那块,那块也是你的)
当段界限为这两个值时,段是最小的 (0xFFFF(0xFFFFFFFF) -0xFFFF(0xFFFFFFFF)) =0 )

而当段界限为0时,段是最大的 ( 0xFFFF(0xFFFFFFFF) -0) = 0xFFFF(0xFFFFFFFF)= 0xFFFF(0xFFFFFFFF))
这种情况下段内偏移量的范围为 0xFFFF ~ 0 或者 0xFFFFFFFF ~ 0
同样是段界限为0的情况,如果G位=1 即粒度是4KB,也是一样的,只不过右端不再是0,而是0xFFF:
0xFFFF/0xFFFFFFFF ~ 0xFFF

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值