清华OS前置知识:80386处理器

保护模式在实模式下初始化控制寄存器,如(GDTR,LDTR等)以及页表,然后通过设置CR0寄存器使其中的保护模式使能位置位,进入保护模式,该模式下80386支持优先级机制,不同的程序运行在不同的特权级上,共0~3四个级别,操作系统在最高的特权级0上

不同模式下寻址方式:

物理地址:内存中的真实地址

实模式下

逻辑地址:段地址和偏移地址

逻辑地址=物理地址,因为此时没有分段或分页机制(所谓的段地址是人为看作一个段的首地址,而不是系统的机制)

实模式下每一个指针都指向实际的物理地址,可以轻易修改其中的内容,不安全

保护模式下

线性地址:线性地址空间中的一个地址

线性地址空间是80386处理器通过段机制控制下形成的地址空间,在操作系统的管理下,每个运行的用程序有相对独立的一个或多个内存空间段,每个段有各自的起始地址和长度属性,这样使应用程序之间相互隔离,实现对地址空间的保护

逻辑地址(也称虚拟地址):16位段选择子 + 32位段内偏移

int boo = 1;
int *foo = &boo;

boo是一个整型变量,foo变量是一个指向boo地址的整型指针变量,foo中存储的内容就是boo的逻辑地址

系统采用段式管理机制来实现逻辑地址到线性地址的转换

未启动启页机制时,逻辑地址(通过段基址处理)生成线性地址=物理地址

在页机制开启后,逻辑地址(通过段机制处理)生成线性地址,随后生(通过页机制处理)成物理地址。

关于实模式和保护模式下的寻址:

因为8086CPU地址总线为20位而寄存器、数据总线只有16位,无法存储和传送20位的数据,才不得不采取段地址左移4位的方式。

32位机的数据总线、寄存器、地址总线都是32位,可直接给出一个32位数就能找到对应的地址,因此不再需要段地址左移的用法,但是为了向下兼容,保留了16位寻址模式,即实模式

保护模式下的寻址可以采取基址+偏移的方式,但不同的是,这里的基址无需进行左移处理,所有的32位的通用寄存器都可以作为基址寄存器(存储basepointer),除ESP之外的通用寄存器都可以作为变址寄存器(存储indexpointer),变址寄存器允许乘以1/2/4/8作为比例因子(indexscale),最后还允许加上一共8/32位的偏移量(immed32)

AT&T:immed32(basepointer, indexpointer, indexscale)	
	  =imm32 + basepointer + indexpointer x indexscale
Intel:	[basepointer + indexpointer x indexscale + imm32]

要注意,尽管通用寄存器、标志寄存器都已经扩展到32位,但段寄存器依旧是16位的,可以理解为为了兼容8086PC机的段地址:偏移地址的寻址方式

在保护模式下使用段地址:偏移地址的寻址模式时(即使用分段机制),段寄存器中存放的不再是段基址了,而是存放了一个段选择子,又称段选择符,一个选择子对应一个长64-bit的描述符,其中有32bit是段基址,另32位存储着段的长度、属性等内容,由于内存中不止一个段,因此也需要多个段描述符,所以把段描述符集中存储在一块连续的存储空间里,排上序号,这就有了描述符表GDT,因此我们需要先找到描述符表的基地址,在32位CPU中,有一个48位的专用寄存器GDTR存储着全局描述符表的基地址等信息,而段寄存器中选择子的高13位存储着相应描述符的序号,段寄存器的功能就是选择描述符,所以也把段寄存器叫做段选择器,在得到了段的基地址,加上了偏移地址以后(段地址无需左移),我们便得到了“中间地址”–线性地址,接着通过页机制最终得到物理地址,当然,如果没有页机制,则线性地址就是物理地址了

32

9

参考博客:计算机地址与8086寻址方式以及32位处理器的寻址方式

32位cpu寻址小结

32位保护模式内存寻址原理

80386CPU加电后的第一条指令问题

80386CPU将BIOS ROM编址在32位内存地址空间的最高端,即4GB地址的最后一个64KB内

解释:如果和8086一样,把BIOS编址在1MB内存地址空间的最高64KB中,因为BIOS是只读的,则内存(这里指RAM)就会被一块ROM分隔成不连续的两端,很不协调

加电之后,CPU进入实模式,将CS的值设置为0xF000,CS的shadow register的Base值初始化为0xFFFF0000,EIP寄存器初始化为0x0000FFF0,所以第一条指令的物理地址为0xFFFFFFF0

解释:虽然说实模式下计算地址需要CS中的地址进行移位,但是Intel规定这种计算方式是在CS中的初始值被改变以后才使用,所以未改变之前是用Base+EIP的计算方式

解释上面的解释:上面提到的Base,是一个寄存器,而不是GDT中的base(这时候还没有GDT),现代的CPU为每个段寄存器增加了两个寄存器:Base和Limit,它们的值不能通过指令读写,而是由CPU自动设置的

补充:在实模式下,Base寄存器的值等于CS的值左移4位,在保护模式下,根据段选择子在GDT中找到对应段描述符,其中base部分的值会更新到对应段寄存器的Base寄存器中,然后进行基址+偏移地址的计算

总结:归根结底,80386地址的计算方式都是Base+IP/EIP,只不过Base寄存器中的值在不同情况下来源不同,可以是初始状态下的值,可以来自对CS值的移位,也可以来自GDT表

该地址上有一条长跳转指令,该长跳转指令会更新CS寄存器和它的shadow register,执行完后,表面CS没有变化,但其shadow register已经被更新,其Base值为0x000F0000,此时的物理地址为0x000FE05B。此时的地址在1M以内了,且位于RAM 中,Intel设计了一种映射机制,将高地址的BIOS ROM映射到1MB以内的RAM空间,使其具有只读属性,即1M空间里最高的64KB的内容和4GB里最高的64KB的内容相同

Intel 80386寄存器

通用寄存器:EAX/EBX/ECX/EDX/ESI/EDI/ESP/EBP,低16位就是8086的AX/BX/CX/DX/SI/DI/SP/BP

寄存器含义
EAX累加器
EBX基址寄存器
ECX计数器
EDX数据寄存器
ESI源地址指针寄存器
EDI目的地址指针寄存器
EBP基址指针寄存器
ESP堆栈指针寄存器

段寄存器:除了8086的CS/DS/ES/SS,增加了FS/GS,都是16位的,用于不同属性内存段的寻址

注:CS在实模式和保护模式下有着不同的含义

寄存器含义
CS代码段(Code Segment)
DS数据段(Data Segment)
ES附加数据段(Extra Segment)
SS堆栈段(Stack Segment)
FS附加段
GS附加段

指令指针寄存器:EIP的低16位就是8086的IP,存储下一条要执行指令的内存地址,在分段地址转换中,表示指令的段内偏移地址

标志寄存器:EFALGS,比8086的16位标志寄存器增加了4个控制位,共20个控制位

CF(Crray Flag):进位标志位
PF(Parity Flag):奇偶标志位
AF(Assistant Flag):辅助进位标志位
ZF(Zero Flag):零标志位
SF(Signal Flag):符号标志位
IF(Interrupt Flag):中断允许标志位,由CLI,STI控制
DF(Direction):向量标志位,由CLD,STD控制
OF(Overfolw Flag):溢出标志位
IOP(I/0 Privilege Level):I/O特权级字段,宽度2位,指定了I/O指令的特权级,如果当前特权级别在数值上小于或等于IOPL,则可执行,否则发生一个保护性故障中断
NT(Nested Task):控制中断返回指令IRET,宽度为1,若NT=0,则用堆栈中保存的值恢复EFALGS,CS,EIP。从而实现中断返回,若NT=1,则通过任务切换实现中断返回,在ucore中,设置NT为0

还有一些应用程序无法访问的控制寄存器,如CR0,CR2,CR3……

  • 1
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值