• CPU工作模式:执行程序的三种模式


    1)CPU 的工作模式有哪三种?

    • 实模式、保护模式、长模式

    2)如果下面这段应用程序代码能够成功运行,会有什么后果?

     
     int main()
     {
         int* addr = (int*)0;
         cli(); //关中断,什么信号来都不能终止CPU
         while(1)
        {
             *addr = 0;
             addr++;
        }
         return 0;
     }
    • 在实模式下,这段代码确实能运行。

    3)什么是实模式?

    • 实模式又称实地址模式,实,即真实,这个真实分为两个方面

    • 一是运行真实的指令,对指令的动作不作区分,指令让干什么就老老实实干什么。另一方面是发往内存的地址是真实的,对任何地址不加限制地发往内存。

    4)实模式下的寄存器有哪些?

     

    5)实模式下访问内存需要获取地址值,这个值是如何计算的呢?

     

    6)分段内存管理模型是什么样的?

    • 所有的内存地址都是由段寄存器左移 4 位,再加上一个通用寄存器中的值或者常数形成地址,然后由这个地址去访问内存

    7)代码段由哪两个寄存器确定?

    • CS 和 IP

    8)栈段由哪两个寄存器确定?

    • SS 和 SP

    9)分析下面代码?

     
     data SEGMENT ;定义一个数据段存放Hello World!
         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高8位,AL是AX低8位,其它类似
         INT 21h     ;执行DOS中断输出DS指向的DX指向的字符串hello
         MOV AX,4C00h ;给AX设置参数4C00h
         INT 21h     ;调用4C00h号功能,结束程序
     code ENDS
     END start
    • LEA 是取地址指令,MOV 是数据传输指令

    10)什么是中断?

    • 停下当前手头上干的事,转而跳转到另一个特定的地址上,去运行特定的代码。

    11)在实模式下中断是如何实现的?

    • 先保存 CS 和 IP 寄存器,然后装载新的 CS 和 IP 寄存器。

    12)中断是如何产生的呢?

    • 第一种情况:中断控制器问CPU在吗,CPU回答在的。随后中断控制器会将中断号发送给 CPU,这是硬件中断。

    • 第二种情况:CPU 执行了 INT 指令,这个指令后面会跟随一个常数,这个常数即是软中断号。这种情况是软件中断。

    13)内存对我们的中断提供了哪些支持?

    • 内存中有中断向量表。地址和长度由 CPU 的特定寄存器 IDTR 指向。

    • 实模式下,表中的一个条目由代码段地址和段内偏移组成。

    有了中断号以后,CPU 就能根据 IDTR 寄存器中的信息,计算出中断向量中的条目,进而装载 CS(装入代码段基地址)、IP(装入代码段内偏移)寄存器,最终响应中断。

    14)什么是保护模式?

    • 因为CPU在实模式下容易出错,所以有了保护模式。

    15)保护模式相比于实模式有哪些变化?

    • 增加了一些控制寄存器和段寄存器,扩展通用寄存器的位宽,所有的通用寄存器都是 32 位的,还可以单独使用低 16 位,这个低 16 位又可以拆分成两个 8 位寄存器,如下表。

    16)R0到R3谁大?

    • R0 拥有最大权力,可以访问低特权级的资源,反之则不行。

    • 上面的圆环图,从外到内,既能体现权力的大小,又能体现各特权级对资源控制访问的多少,还能体现各特权级之间的包含关系。R0 拥有最大权力,可以访问低特权级的资源,反之则不行。

    17)什么是保护模式段描述符?

    • 由于 CPU 的扩展导致了 32 位的段基地址和段内偏移,还有一些其它信息,所以 16 位的段寄存器肯定放不下。多出来的这部分就放内存,打包成段描述符。

    18)内存中多个段描述符叫什么?

    • 全局段描述符表

    • 该表的基地址和长度由 CPU 和 GDTR 寄存器指示。

       

    19)有了段描述符之后是怎么访问内存的?

    • 段寄存器中不再存放段基地址,而是具体段描述符的索引,访问一个内存地址时,段寄存器中的索引首先会结合 GDTR 寄存器找到内存中的段描述符,再根据其中的段信息判断能不能访问成功。

    20)CS、DS、ES、SS、FS、GS 这些段寄存器,里面存放的就是一个内存段的描述符索引吗?

    • 由影子寄存器、段描述符索引、描述符表索引、权限级别组成

    20.1)影子寄存器是什么?

    • 靠硬件来操作的,对系统程序员不可见,是硬件为了减少性能损耗而设计的一个段描述符的高速缓存,不然每次内存访问都要去内存中查表,那性能损失是巨大的,影子寄存器也正好是 64 位,里面存放了 8 字节段描述符数据。

    21)什么是保护模式平坦模型?

    • 内存分段的话有很多缺点,现代操作系统都是用分页。但是X86CPU并不能直接使用分页模型,而是在分段模型的基础上,根据需要决定是否要开启分页,这是硬件的规定,我们无法改变。但是我们可以通过设计来把分段变为一种虚设。这个就叫保护模式的平坦模型。

    22)回过头去看看我们前面的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
    • 上面代码中注释已经很明白了,段长度需要和 G 位配合,若 G 位为 1 则段长度等于 0xfffff 个 4KB。上面段描述符的 DPL=0,这说明需要最高权限即 CPL=0 才能访问。

     

    23)保护模式下中断是怎样处理的?

    • 保护模式下的中断要权限检查,还有特权级的切换,所以就需要扩展中断向量表的信息,即每个中断用一个中断门描述符来表示,也可以简称为中断门,中断门描述符依然有自己的格式,如下图所示。

    • 同样的,保护模式要实现中断,也必须在内存中有一个中断向量表,同样是由 IDTR 寄存器指向,只不过中断向量表中的条目变成了中断门描述符

    24)保护模式下cpu收到中断后,会采取哪些措施?

    • 检查中断号是否大于最后一个中断门描述符(0-255),然后检查描述符类型(是否是中断门或者陷阱门),是否为系统描述符,是不是存在于内存中。

    • 接着,检查中断门描述符中的段选择子指向的段描述符。

    • 最后做权限检查,如果 CPL 小于等于中断门的 DPL,并且 CPL 大于等于中断门中的段选择子所指向的段描述符的 DPL,就指向段描述符的 DPL。

    25)我们的CPU默认是实模式的,那怎样进入保护模式?

    • 第一步,准备全局段描述符表,代码如下。

       
       GDT_START:
       knull_dsc: dq 0
       kcode_dsc: dq 0x00cf9e000000ffff
       kdata_dsc: dq 0x00cf92000000ffff
       GDT_END:
       GDT_PTR:
       GDTLEN dw GDT_END-GDT_START-1
       GDTBASE dd GDT_START
    • 第二步,加载设置 GDTR 寄存器,使之指向全局段描述符表。

       
       lgdt [GDT_PTR]
    • 第三步,设置 CR0 寄存器,开启保护模式。

       
       ;开启 PE
       mov eax, cr0
       bts eax, 0                     ; CR0.PE =1
       mov cr0, eax        
    • 第四步,进行长跳转,加载 CS 段寄存器,即段选择子。

       
       jmp dword 0x8 :_32bits_mode ;_32bits_mode为32位代码标号即段偏移

    26)为什么要进行长跳转?

    • 我们无法直接或间接 mov 一个数据到 CS 寄存器中,因为刚刚开启保护模式时,CS 的影子寄存器还是实模式下的值,所以需要告诉 CPU 加载新的段信息。

    27)什么是长模式?

    • 使 CPU 在现有的基础上有了 64 位的处理能力

    28)长模式相比于保护模式有什么变化?

    • 增加了一些通用寄存器,并扩展通用寄存器的位宽,所有的通用寄存器都是 64 位,还可以单独使用低 32 位。

    • 这个低 32 位可以拆分成一个低 16 位寄存器,低 16 位又可以拆分成两个 8 位寄存器

    29)长模式下段描述的格式是什么样的?

     

     
     ex64_GDT:
     null_dsc: dq 0
     ;第一个段描述符CPU硬件规定必须为0
     c64_dsc:dq 0x0020980000000000 ;64位代码段
     ;无效位填0
     ;D/B=0,L=1,AVL=0
     ;P=1,DPL=0,S=1
     ;T=1,C=0,R=0,A=0
     d64_dsc:dq 0x0000920000000000 ;64位数据段
     ;无效位填0
     ;P=1,DPL=0,S=1
     ;T=0,C/E=0,R/W=1,A=0
     eGdtLen   equ $ - null_dsc ;GDT长度
     eGdtPtr:dw eGdtLen - 1 ;GDT界限
          dq ex64_GDT

     

  • 相关阅读:
    mysql 应用 持续更新2 转载
    sql server 用触发器记录增删改操作(转载)
    mysql 应用 持续更新
    oracle 常用指令(持续更新中....)
    转载-Oracle 数据库导入导出 dmp文件
    Web Service 服务无法连接Oracle数据库
    关于jquery获取服务器端xml数据
    Navicat Premium 自动备份mysql和sqlserver
    浅谈如何更好的打开和关闭ADO.NET连接池
    JSON 的优点
  • 原文地址:https://www.cnblogs.com/YXBLOGXYY/p/16009403.html
Copyright © 2020-2023  润新知