cpu工作模式有实模式、保护模式、长模式
又称地址模式,运行真实的指令,执行指令的真实功能,发往内存的地址是真实的
CPU是根据指令完成相应的功能,例如ADD,AX,CX这条指令,就是完成加法操作,AX,CX是这条指令的操作数,操作数可以是,寄存器、内存地址、常数
通用寄存器:里面可以存放数据、地址参与运算
程序指针寄存器(IP):始终指向下一条指令的地址
栈指针寄存器(SP):始终指向当前运行的栈顶
段寄存器(CS、DS、ES、SS):存放一个内存段的基地址
CPU标志寄存器(FLAGS):存放CPU执行运算指令产生的状态位
数据和指令都是存放在内存中的,获取它们要访问内存靠地址值
取指地址:CS段寄存器(左移四位)+ IP寄存器
访问数据地址:DS、ES、SS段寄存器(左移四位)+ 寄存器
综上代码段是由CS和IP确定的,而栈段是由SS和SP段确定的
data SEGMENT ;定义一个数据段存放Hello Word!
hello DB 'Hello world!$'
data ENDS
code SEGMENT ;定义一个代码段存放程序指令
ASSUME CS:CODE,DS:DATA ;告诉汇编程序,DS指向数据段,CS指向代码段
start:
MOV AX,data ;将data段首地址赋值给AX
MOV DS、AX ;将AX赋值给DS,使DS指向data段
LEA DX,hello ;使DX指向hello首地址
MOV AH,09h ;给AH设置参数09h,AH是AX高八位,AL是AX第八位
INT 21h ;执行DOS中断输出DS指向DX指向的字符串hello
MOV AX,4C00h ;给AH设置参数4C00h
INT 21h ;调用4C00h号功能,结束进程
code ENDS
END start
中断即中止执行当前程序,转而跳转到另一个特定的地址上去运行其他代码。在实模式下实现过程是先保存CS和IP寄存器,然后重新装载新的CS和IP寄存器
中断如何产生
第一种情况:中断控制器给CPU发送一个电子信号,CPU做出应答,随后中断控制器将中断号发送给CPU,这是硬件中断
第二种情况:CPU执行了INT指令,这个指令后面通常会跟一个常数(软中断号),这是软件中断
为了实现中断,需要在内存中存放一个中断向量表,表的地址和长度由CPU特定寄存器IDTR指向,实模式下,表中的一个条目由代码段地址和段内偏移组成
有了中断号,CPU就根据IDTR寄存器计算出中断向量中的条目,进而装载CS(状如代码段及地址)IP(装入代码段内偏移),最后响应中断
实模式导致什么样的代码都可以运行,原因有两点,第一,CPU对任何指令不加区分的执行,第二,CPU对访问内存的地址不加限制
综上所述,CPU实现了保护模式。
32位通用寄存器:里面可以存放数据、地址、参与运算
32位指针寄存器:始终指向下一条指令的地址
栈指针寄存器:始终指向当前栈顶
16位段寄存器:里面存放一个内存段的描述符索引
32位CPU标志寄存器:里面存放CPU执行运算指令产生的状态位
32位CPU控制寄存器:控制CPU的功能控制特性,如开启保护模式
为了区分哪些指令(如in、out、cli)和哪些资源(如寄存器、I/O端口、内存地址)可以被访问,CPU实现了特权级
特权级分为四级R0~R3,R0可以执行所有指令。内存的访问是靠段描述符和特权级相互配合去实现
16位段寄存器放不下32位的段基地址和段内偏移,把描述一个段的信息封装成特定格式的段描述符,放在内存中
多个段描述符在内存中形成全局段描述表,该表的基地址和长度由CPU和GDTR寄存器指示
访问一个内存地址时,段寄存器中的索引首先会结合GDTR寄存器找到内存中的段描述符,再根据其中的段信息判断能不能访问成功
CS DS ES SS FS GS这些段寄存器,都是由影子寄存器,段描述符索引,描述符表索引,权限级别组成
影子寄存器是一个段描述符的高速缓存,不然每次都要去内存访问
通常CS和SS中的RPL就组成了CPL(当前权限级别),所以通常RPL=CPL,当CPL大于目标段DPL时,CPU禁止访问,反之CPU可以访问
X86CPU不能直接使用分页模型,而是要在分段模型的前提下,根据需要决定是否分页。我们可以简化设计使分段称为“虚设”,这就是平坦模型
CPU32位寄存器最多只能产生4GB大小的地址,而一个段长度也只能是4GB,我们把所有段的基地址设为0,段的长度设为0xFFFFF,段长度的粒度设为4KB,这样所有的段都指向同一个字节大小的地址空间
;hello OS中段描述符表
GDT_START:
knull_dsc:dq 0
;第一个段描述符cpu硬件规定必须为0
kcode_dsc:dq 0x00cf9e000000ffff
;段基地址=0,段长度=0xfffff
;G=1,D/B=1,L=0,AVL=0
;P=1,DPL=0,s=1
;T=1,C=1,R=1,A=0
kdata_dsc: dq 0x00cf92000000ffff
;段基地址=0,段长度=0xfffff
;G=1,D/B=1,L=0,AVL=0
;P=1,DPL=0,S=1
;T=0,C=0,R=1,A=0
GDT_END
GDT_PTR:
GDTLEN dw GDT_END-GDT_START-1
GDTBASE dd GDT_START
保护模式下的中断要权限检查,还有特权级的切换,需要扩展中断向量表的信息,每一个中断用一个中断门描述符表示
要实现中断,内存中要有一个中断向量表,是由IDTR寄存器指向,中断向量表中的条目是中断门描述符
产生中断后,CPU会先检查中断号,接着检查中断门描述符中的段选择子指向的段描述符,最后权限检查
64位处理能力
增加了通用寄存器,扩展了通用寄存器的位宽
64位通用寄存器
64位程序指针寄存器
栈指针寄存器
16位段寄存器
64位CPU标志寄存器
64位CPU控制寄存器(CR0是32位)
CPU不再对段基址和段长度进行检查,只对DPL进行相关的检查
同样在内存中有一个中断门描述符表
1.实模式:早期CPU位置支持单道程序运行实现,单道程序能掌控计算机所有的资源,分段的内存模型,对指令不加限制地运行,对内存没有保护隔离作用
2.保护模式:包含特权级,对指令及其访问的资源进行控制,对内存段与段之间的访问进行严格的检查,对中断的响应也要进行严格的权限检查
3.长模式:在保护模式的基础上,把寄存器扩展到64位。弱化了段模式管理,只保留了权限级别的检查,忽略了段基址和段长度,地址的检验交给MMU