鱼C论坛

 找回密码
 立即注册
查看: 3369|回复: 2

[学习笔记] 【原创】保护模式JMP指令-远跳转相关翻译资料(3)-JMP跳转过程逻辑说明

[复制链接]
发表于 2017-12-23 22:05:32 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
本帖最后由 兰陵月 于 2017-12-23 22:28 编辑



                               
登录/注册后可看大图

                               
登录/注册后可看大图
下面为JMP指令跳转的过程逻辑说明

                               
登录/注册后可看大图

                               
登录/注册后可看大图

        
        IF
                ;如果是远程跳转并且指令运行于保护模式下(非虚拟8086模式)的情况。
                far jump and (PE = 1 and VM = 0)
                (* IA-32e mode or protected mode, not virtual-8086 mode *)
        THEN
               
                ;检查1:
                ;如果CS、DS、ES、FS、GS、SS段中的有效地址是非法的,或者目标操作数中的段选择子是空
                ;引发GP(0)异常
                IF
                        effective address in the CS, DS, ES, FS, GS, or SS segment is illegal
                        or segment selector in target operand NULL                        
                THEN
                        #GP(0) ;FI;
               
                ;检查2:
                ;如果段选择器索引值不在描述符表的范围内
                ;引发GP(new selector)异常
                IF
                        segment selector index not within descriptor table limits
                THEN
                        #GP(new selector) ;FI;
               
                ;读取段描述符的类型和访问权限
                Read type and access rights of segment descriptor;
               
                ;检查3:
                ;长模式(X86扩展的64位环境,即IA-32e)环境下的检查               
                IF
                        (EFER.LMA = 0);不是处于长模式下
                THEN               
                        ;如果不是处于长模式下,且段类型不是一致或非一致代码段、调用门、任务门、TSS
                        ;引发异常。
                        IF
                                segment type is not a conforming or nonconforming code segment, call gate, task gate, or TSS
                        THEN
                                #GP(segment selector); FI;
                ELSE
                        ;如果处于长模式下,且段类型不是一致或非一致代码段,调用门,
                        ;引发异常。
                        IF
                                segment type is not a conforming or nonconforming code segment,call gate
                        THEN
                                #GP(segment selector) ; FI;
                ;FI;              


                               
登录/注册后可看大图

              上述几种检查基本上都是属于合法性检查

              没有针对特权级进行检查

                               
登录/注册后可看大图

               
                ;检查合格后,根据段描述符的类型和访问权限,进行跳转
                ;        转移至一致代码段,位于第85行
                ;        转移至非一致代码段,位于第160行
                ;        转移至调用门,位于第228行
                ;        转移至任务门,位于第339行
                ;        转移至任务状态段TSS,位于第34行
                Depending on type and access rights:
                        GO TO CONFORMING-CODE-SEGMENT;
                        GO TO NONCONFORMING-CODE-SEGMENT;
                        GO TO CALL-GATE;
                        GO TO TASK-GATE;
                        GO TO TASK-STATE-SEGMENT;
        
        ;如果不是——远程跳转并且指令运行于保护模式下(非虚拟8086模式)——的情况,
        ;根据段选择子情况进行其他处理。
        ELSE
                #GP(segment selector) ;FI;


                               
登录/注册后可看大图

         下面的检查就开始有了特权级的检查内容

                               
登录/注册后可看大图
   
     
        ;转移至一致代码段
        CONFORMING-CODE-SEGMENT:
               
                ;检查1:
                ;如果段描述符的L位=1、D位=1、长模式处于开启激活状态
                ;L位=1表示这个一个64代码段
                ;D位=1表示默认32位偏移地址或者操作数
                ;IA32_EFER.LMA=1表示长模式处于激活状态
                ;如果上述三种条件成立,则终止当前操作,获取新的代码段选择子。
                IF
                        L-Bit = 1 and D-BIT = 1 and IA32_EFER.LMA = 1
                THEN
                        GP(new code segment selector)  ; FI;
               
                ;检查2:
                ;如果指令的当前特权级CPL小于读取的段描述符的DPL
                ;表明当前特权级高于要访问的段特权级
                ;引发异常。
                IF
                        DPL > CPL
                THEN
                        #GP(segment selector) ; FI;
               
                ;检查3:
                ;如果要访问的段不存在
                ;引发异常
                IF
                        segment not present
                THEN
                        #NP(segment selector); FI;
               
                ;上述所有检查都通过后,
                ;将目标操作数的偏移地址(偏移量)给临时EIP。
                tempEIP ← DEST(Offset);
               
                ;如果操作数类型是16位的,
                ;则将32位临时偏移量的高16位清零
                IF
                        OperandSize = 16
                THEN
                        tempEIP ← tempEIP AND 0000FFFFH  ;FI;
               
                ;如果临时EIP数值超过代码段的界限
                ;并且长模式未激活、目标模式为兼容模式这两个条件有一个成立
                ;引发异常
                IF
                        (IA32_EFER.LMA = 0 or target mode = Compatibility mode) and tempEIP outside code segment limit
                THEN
                        #GP(0)   ; FI
               
                ;如果临时EIP数值不规范
                ;引发异常
                IF
                        tempEIP is non-canonical
                THEN
                        #GP(0)                ; FI;
               
                ;当上述检查全部通过
              ;则将目标段选择子加载到CS段选择器
              ;段描述符的信息也加载到CS段选择器的不可见部分
              ;将当前指令的特权级数值写入CS段选择器的RPL部分
              ;将临时EIP数值传送给真正的EIP寄存器
              ;指令从新的CS:EIP处开始执行。
              ;第155行,可以看到跳转后的CPL仍是跳转前的CPL。
CPL未发生变化
              CS ← DEST[segment selector]; (* Segment descriptor information also loaded *)
              CS(RPL) ← CPL
              EIP ← tempEIP;

        END;
        
        ;跳转到非一致代码段
        NONCONFORMING-CODE-SEGMENT:
               
                ;检查1:
                ;如果段描述符的L位=1、D位=1、长模式处于开启激活状态
                ;L位=1表示这个一个64代码段
                ;D位=1表示默认32位偏移地址或者操作数
                ;IA32_EFER.LMA=1表示长模式处于激活状态
                ;如果上述三种条件成立,则终止当前操作,获取新的代码段选择子。
                IF
                        L-Bit = 1 and D-BIT = 1 and IA32_EFER.LMA = 1
                THEN
                        GP(new code segment selector); FI;
               
                ;检查2:
                ;如果条件1:指令的当前特权级CPL小于段选择子的请求特权级(说明请求权限不够)
                ;或者条件2:当前特权级CPL不等于目标段描述符特权级DPL(非一致代码段只能同特权级访问,否则不能访问)
                ;条件1、条件2有1个成立,则会引发异常。
                IF
                        (RPL > CPL) OR (DPL ≠ CPL)
                THEN
                        #GP(code segment selector); FI;
               
                ;检查3:
                ;如果要访问的段不存在
                ;引发异常
                IF
                        segment not present
                THEN
                        #NP(segment selector); FI;
               
                ;上述所有检查都通过后,
                ;将目标操作数的偏移地址(偏移量)给临时EIP。
                tempEIP ← DEST(Offset);
               
                ;如果操作数类型是16位的,
                ;则将32位临时偏移量的高16位清零
                IF
                        OperandSize = 16
                THEN
                        tempEIP ← tempEIP AND 0000FFFFH; FI;
               
                ;如果临时EIP数值超过代码段的界限
                ;并且长模式未激活、目标模式为兼容模式这两个条件有一个成立
                ;引发异常
                IF
                        (IA32_EFER.LMA = 0 OR target mode = Compatibility mode)and tempEIP outside code segment limit
                THEN
                        #GP(0); FI
               
                ;如果临时EIP数值不规范
                ;引发异常
                IF
                        tempEIP is non-canonical
                THEN
                        #GP(0); FI;
               
                ;当上述检查全部通过
                ;则将目标段选择子加载到CS段选择器,段描述符的信息也加载到CS段选择器的不可见部分
                ;将当前指令的特权级数值写入CS段选择器的RPL部分
                ;将临时EIP数值传送给真正的EIP寄存器
                ;指令从新的CS:EIP处开始执行。
                ;第223行,可以看到跳转后的CPL仍是跳转前的CPL。【CPL未发生变化】

                CS ← DEST[segment selector]; (* Segment descriptor information also loaded *)
              CS(RPL) ← CPL;
             EIP ← tempEIP;

        END;

        ;通过调用门跳转
        CALL-GATE:
               
                ;检查1:
                ;条件1:调用门DPL小于CPL—表明当前特权级比调用门特权级低
                ;条件2:调用门DPL小于调用门段选择子RPL—表明请求特权级比调用门特权级低
                ;上述两个条件中如果有1个或1个以上成立,引发异常
                ;要通过检查的话,必须下面两个条件同时成立:
                ;1、CPL小于等于调用门DPL;2、调用门选择子RPL小于等于调用门DPL。
                IF
                        call gate DPL < CPL or call gate DPL < call gate segment-selector RPL
                THEN
                        #GP(call gate selector); FI;

                ;检查2:
                ;如果调用门不存在
                ;引发异常。
                IF
                        call gate not present
                THEN
                        #NP(call gate selector); FI;

                ;检查3:
                ;如果调用门所调用代码段的选择子为空
                ;引发异常
                IF
                        call gate code-segment selector is NULL
                THEN
                        #GP(0); FI;

                ;检查4:
                ;如果调用门所调用代码段的选择子索引超出描述表的界限
                ;引发异常
                IF
                        call gate code-segment selector index outside descriptor table limits
                THEN
                        #GP(code segment selector); FI;
               
                ;读取要调用的代码段的描述符
                Read code segment descriptor;
               
                ;检查5:
                ;条件1:要调用的目标代码段段描述符不是指向一个代码段
                ;条件2:要调用的目标代码段是一致的且CPL小于DPL
                ;条件3:要调用的目标代码段是非一致的且CPL不等于DPL
                ;上述条件中有1个或1个以上成立,则引发异常
                IF
                        code-segment segment descriptor does not indicate a code segment
                        or code-segment segment descriptor is conforming and DPL > CPL
                        or code-segment segment descriptor is non-conforming and DPL ≠ CPL
                THEN
                        #GP(code segment selector); FI;
               
                ;检查6:
                ;条件1:长模式处于激活状态
                ;条件2:代码段描述符指向的不是一个64位代码段
                ;条件3:代码段描述符L位和D位同时置1
                ;当条件1成立且条件2或者3中有1个或1个以上成立时,
                ;引发异常
                IF
                        IA32_EFER.LMA = 1 and (code-segment descriptor is not a 64-bit code segment
                        or code-segment segment descriptor has both L-Bit and D-bit set)
                THEN
                        #GP(code segment selector); FI;
               
                ;检查7
                ;如果代码段不存在
                ;引发异常
                IF
                        code segment is not present
                THEN
                        #NP(code-segment selector); FI;
               
                ;检查8
                ;如果指令指针指向的指令不在代码段界限内
                ;引发异常
                IF
                        instruction pointer is not within code-segment limit
                THEN
                        #GP(0); FI;
               
                ;上述所有检查都通过后,
                ;将目标操作数的偏移地址(偏移量)给临时EIP。
                tempEIP ← DEST(Offset);
               
                ;如果操作数类型是16位的,
                ;则将32位临时偏移量的高16位清零
                IF
                        GateSize = 16
                THEN
                        tempEIP ← tempEIP AND 0000FFFFH; FI;
               
                ;如果临时EIP数值超过代码段的界限
                ;并且长模式未激活、目标模式为兼容模式这两个条件有一个成立
                ;引发异常
                IF
                        (IA32_EFER.LMA = 0 OR target mode = Compatibility mode) AND tempEIP outside code segment limit
                THEN
                        #GP(0); FI
               
                ;当上述检查全部通过
              ;则将目标段选择子加载到CS段选择器,段描述符的信息也加载到CS段选择器的不可见部分
              ;将当前指令的特权级数值写入CS段选择器的RPL部分
              ;将临时EIP数值传送给真正的EIP寄存器
              ;指令从新的CS:EIP处开始执行。
              ;第334行,可以看到跳转后的CPL仍是跳转前的CPL。【CPL未发生变化】

                CS ← DEST[SegmentSelector]; (* Segment descriptor information also loaded *)
             CS(RPL) ← CPL;
              EIP ← tempEIP;

        END;

        ;跳转到任务门
        TASK-GATE:
               
                ;检查1
                ;条件1:任务门描述符DPL小于CPL-表明当前特权级低于任务门描述符特权级
                ;条件2:任务门描述符DPL小于任务门选择子RPL-表明请求特权级低于任务门描述符特权级
                ;上述2个条件中有1个或者1个以上成立,则引发异常
                IF
                        task gate DPL < CPL or task gate DPL < task gate segment-selector RPL
                THEN
                        #GP(task gate selector); FI;

                ;检查2
                ;如果任务门不存在
                ;引发异常
                IF
                        task gate not present
                THEN
                        #NP(gate selector); FI;
               
                ;读取任务门描述符中的TSS段选择子
                Read the TSS segment selector in the task-gate descriptor;
               
                ;检查3
                ;条件1:TSS段选择子TI位被设置成1
                ;条件2:TSS段选择子的索引不在GDT界限内
                ;条件3:TSS描述符中的B位为1,处于忙的装填。
                ;上述3个条件中有1个或者1个以上条件成立,则引发异常。
                IF
                        TSS segment selector local/global bit is set to local
                        or index not within GDT limits
                        or TSS descriptor specifies that the TSS is busy
                THEN
                        #GP(TSS selector); FI;

                ;检查4
                ;如果TSS不存在
                ;引发异常
                IF
                        TSS not present
                THEN
                        #NP(TSS selector); FI;
               
                ;转换任务到TSS
                SWITCH-TASKS to TSS;
               
                ;检查5
                ;如果EIP指向的指令不在代码段界限内
                ;引发异常
                IF
                        EIP not within code segment limit
                THEN
                        #GP(0); FI;
        END;

        ;跳转到TSS
        TASK-STATE-SEGMENT:
               
                ;检查1
                ;条件1:TSS的DPL小于CPL-表明当前特权级低于TSS描述符特权级
                ;条件2:TSS的DPL小于TSS段选择子RPL-表明请求特权级低于TSS描述符特权级
                ;条件3:TSS描述符指向的TSS不是有效的
                ;上述3个条件中有1个或者1个以上条件成立,则引发异常。
                IF
                        TSS DPL < CPL
                        or TSS DPL < TSS segment-selector RPL
                        or TSS descriptor indicates TSS not available
                THEN
                        #GP(TSS selector); FI;
               
                ;检查2
                ;如果TSS不存在
                ;引发异常。
                IF
                        TSS is not present
                THEN
                        #NP(TSS selector); FI;
               
                ;切换任务
                SWITCH-TASKS to TSS;
               
                ;检查3
                ;如果EIP指向的指令不在代码段界限内
                ;引发异常
                IF
                        EIP not within code segment limit
                THEN
                        #GP(0); FI;
        END;

Flags Affected(标志影响)
All flags are affected if a task switch occurs,如果发生任务切换,所有标志都会受到影响;
no flags are affected if a task switch does not occur.如果任务切换不发生,则不会影响任何标志。



                               
登录/注册后可看大图

                               
登录/注册后可看大图
代码形式表示如下


                               
登录/注册后可看大图

                               
登录/注册后可看大图

  1.        
  2.         ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  3.         ;;;;;;;;;;下面为JMP指令跳转的逻辑过程说明;;;;;;;;;;
  4.         ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  5.        
  6.         IF
  7.                 ;如果是远程跳转并且指令运行于保护模式下(非虚拟8086模式)的情况。
  8.                 far jump and (PE = 1 and VM = 0)
  9.                 (* IA-32e mode or protected mode, not virtual-8086 mode *)
  10.         THEN
  11.                
  12.                 ;检查1:
  13.                 ;如果CS、DS、ES、FS、GS、SS段中的有效地址是非法的,或者目标操作数中的段选择子是空
  14.                 ;引发GP(0)异常
  15.                 IF
  16.                         effective address in the CS, DS, ES, FS, GS, or SS segment is illegal
  17.                         or segment selector in target operand NULL                       
  18.                 THEN
  19.                         #GP(0)
  20.                 ;FI;
  21.                
  22.                 ;检查2:
  23.                 ;如果段选择器索引值不在描述符表的范围内
  24.                 ;引发GP(new selector)异常
  25.                 IF
  26.                         segment selector index not within descriptor table limits
  27.                 THEN
  28.                         #GP(new selector)
  29.                 ;FI;
  30.                
  31.                 ;读取段描述符的类型和访问权限
  32.                 Read type and access rights of segment descriptor;
  33.                
  34.                 ;检查3:
  35.                 ;长模式(X86扩展的64位环境,即IA-32e)环境下的检查               
  36.                 IF
  37.                         (EFER.LMA = 0);不是处于长模式下
  38.                 THEN               
  39.                         ;如果不是处于长模式下,且段类型不是一致或非一致代码段、调用门、任务门、TSS
  40.                         ;引发异常。
  41.                         IF
  42.                                 segment type is not a conforming or nonconforming code segment, call gate, task gate, or TSS
  43.                         THEN
  44.                                 #GP(segment selector)
  45.                         ; FI;
  46.                 ELSE
  47.                         ;如果处于长模式下,且段类型不是一致或非一致代码段,调用门,
  48.                         ;引发异常。
  49.                         IF
  50.                                 segment type is not a conforming or nonconforming code segment,call gate
  51.                         THEN
  52.                                 #GP(segment selector)
  53.                         ; FI;
  54.                 ;FI;
  55.                
  56.                 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  57.                 ;;;;;上述几种检查基本上都是属于合法性检查,;;;;;
  58.                 ;;;;;没有针对特权级进行检查;;;;;;;;;;;;;;;;;;;;;
  59.                 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  60.                
  61.                 ;检查合格后,根据段描述符的类型和访问权限,进行跳转
  62.                 ;        转移至一致代码段,位于第85行
  63.                 ;        转移至非一致代码段,位于第160行
  64.                 ;        转移至调用门,位于第228行
  65.                 ;        转移至任务门,位于第339行
  66.                 ;        转移至任务状态段TSS,位于第34行
  67.                 Depending on type and access rights:
  68.                         GO TO CONFORMING-CODE-SEGMENT;
  69.                         GO TO NONCONFORMING-CODE-SEGMENT;
  70.                         GO TO CALL-GATE;
  71.                         GO TO TASK-GATE;
  72.                         GO TO TASK-STATE-SEGMENT;
  73.        
  74.         ;如果不是——远程跳转并且指令运行于保护模式下(非虚拟8086模式)——的情况,
  75.         ;根据段选择子情况进行其他处理。
  76.         ELSE
  77.                 #GP(segment selector)
  78.         ;FI;

  79.         ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  80.         ;;;;;下面的检查就开始有了特权级的检查内容;;;;;
  81.         ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  82.        
  83.         ;转移至一致代码段
  84.         CONFORMING-CODE-SEGMENT:
  85.                
  86.                 ;检查1:
  87.                 ;如果段描述符的L位=1、D位=1、长模式处于开启激活状态
  88.                 ;L位=1表示这个一个64代码段
  89.                 ;D位=1表示默认32位偏移地址或者操作数
  90.                 ;IA32_EFER.LMA=1表示长模式处于激活状态
  91.                 ;如果上述三种条件成立,则终止当前操作,获取新的代码段选择子。
  92.                 IF
  93.                         L-Bit = 1 and D-BIT = 1 and IA32_EFER.LMA = 1
  94.                 THEN
  95.                         GP(new code segment selector)
  96.                 ; FI;
  97.                
  98.                 ;检查2:
  99.                 ;如果指令的当前特权级CPL小于读取的段描述符的DPL
  100.                 ;表明当前特权级高于要访问的段特权级
  101.                 ;引发异常。
  102.                 IF
  103.                         DPL > CPL
  104.                 THEN
  105.                         #GP(segment selector)
  106.                 ; FI;
  107.                
  108.                 ;检查3:
  109.                 ;如果要访问的段不存在
  110.                 ;引发异常
  111.                 IF
  112.                         segment not present
  113.                 THEN
  114.                         #NP(segment selector)
  115.                 ; FI;
  116.                
  117.                 ;上述所有检查都通过后,
  118.                 ;将目标操作数的偏移地址(偏移量)给临时EIP。
  119.                 tempEIP ← DEST(Offset);
  120.                
  121.                 ;如果操作数类型是16位的,
  122.                 ;则将32位临时偏移量的高16位清零
  123.                 IF
  124.                         OperandSize = 16
  125.                 THEN
  126.                         tempEIP ← tempEIP AND 0000FFFFH
  127.                 ;FI;
  128.                
  129.                 ;如果临时EIP数值超过代码段的界限
  130.                 ;并且长模式未激活、目标模式为兼容模式这两个条件有一个成立
  131.                 ;引发异常
  132.                 IF
  133.                         (IA32_EFER.LMA = 0 or target mode = Compatibility mode) and tempEIP outside code segment limit
  134.                 THEN
  135.                         #GP(0)
  136.                 ; FI
  137.                
  138.                 ;如果临时EIP数值不规范
  139.                 ;引发异常
  140.                 IF
  141.                         tempEIP is non-canonical
  142.                 THEN
  143.                         #GP(0)
  144.                 ; FI;
  145.                
  146.                 ;当上述检查全部通过
  147.                 ;则将目标段选择子加载到CS段选择器
  148.                 ;段描述符的信息也加载到CS段选择器的不可见部分
  149.                 ;将当前指令的特权级数值写入CS段选择器的RPL部分
  150.                 ;将临时EIP数值传送给真正的EIP寄存器
  151.                 ;指令从新的CS:EIP处开始执行。
  152.                 ;第155行,可以看到跳转后的CPL仍是跳转前的CPL。
  153.                 CS ← DEST[segment selector]; (* Segment descriptor information also loaded *)
  154.                 CS(RPL) ← CPL
  155.                 EIP ← tempEIP;
  156.         END;
  157.        
  158.         ;跳转到非一致代码段
  159.         NONCONFORMING-CODE-SEGMENT:
  160.                
  161.                 ;检查1:
  162.                 ;如果段描述符的L位=1、D位=1、长模式处于开启激活状态
  163.                 ;L位=1表示这个一个64代码段
  164.                 ;D位=1表示默认32位偏移地址或者操作数
  165.                 ;IA32_EFER.LMA=1表示长模式处于激活状态
  166.                 ;如果上述三种条件成立,则终止当前操作,获取新的代码段选择子。
  167.                 IF
  168.                         L-Bit = 1 and D-BIT = 1 and IA32_EFER.LMA = 1
  169.                 THEN
  170.                         GP(new code segment selector); FI;
  171.                
  172.                 ;检查2:
  173.                 ;如果条件1:指令的当前特权级CPL小于段选择子的请求特权级(说明请求权限不够)
  174.                 ;或者条件2:当前特权级CPL不等于目标段描述符特权级DPL(非一致代码段只能同特权级访问,否则不能访问)
  175.                 ;条件1、条件2有1个成立,则会引发异常。
  176.                 IF
  177.                         (RPL > CPL) OR (DPL ≠ CPL)
  178.                 THEN
  179.                         #GP(code segment selector); FI;
  180.                
  181.                 ;检查3:
  182.                 ;如果要访问的段不存在
  183.                 ;引发异常
  184.                 IF
  185.                         segment not present
  186.                 THEN
  187.                         #NP(segment selector); FI;
  188.                
  189.                 ;上述所有检查都通过后,
  190.                 ;将目标操作数的偏移地址(偏移量)给临时EIP。
  191.                 tempEIP ← DEST(Offset);
  192.                
  193.                 ;如果操作数类型是16位的,
  194.                 ;则将32位临时偏移量的高16位清零
  195.                 IF
  196.                         OperandSize = 16
  197.                 THEN
  198.                         tempEIP ← tempEIP AND 0000FFFFH; FI;
  199.                
  200.                 ;如果临时EIP数值超过代码段的界限
  201.                 ;并且长模式未激活、目标模式为兼容模式这两个条件有一个成立
  202.                 ;引发异常
  203.                 IF
  204.                         (IA32_EFER.LMA = 0 OR target mode = Compatibility mode)and tempEIP outside code segment limit
  205.                 THEN
  206.                         #GP(0); FI
  207.                
  208.                 ;如果临时EIP数值不规范
  209.                 ;引发异常
  210.                 IF
  211.                         tempEIP is non-canonical
  212.                 THEN
  213.                         #GP(0); FI;
  214.                
  215.                 ;当上述检查全部通过
  216.                 ;则将目标段选择子加载到CS段选择器,段描述符的信息也加载到CS段选择器的不可见部分
  217.                 ;将当前指令的特权级数值写入CS段选择器的RPL部分
  218.                 ;将临时EIP数值传送给真正的EIP寄存器
  219.                 ;指令从新的CS:EIP处开始执行。
  220.                 ;第223行,可以看到跳转后的CPL仍是跳转前的CPL。
  221.                 CS ← DEST[segment selector]; (* Segment descriptor information also loaded *)
  222.                 CS(RPL) ← CPL;
  223.                 EIP ← tempEIP;
  224.         END;

  225.         ;通过调用门跳转
  226.         CALL-GATE:
  227.                
  228.                 ;检查1:
  229.                 ;条件1:调用门DPL小于CPL—表明当前特权级比调用门特权级低
  230.                 ;条件2:调用门DPL小于调用门段选择子RPL—表明请求特权级比调用门特权级低
  231.                 ;上述两个条件中如果有1个或1个以上成立,引发异常
  232.                 ;要通过检查的话,必须下面两个条件同时成立:
  233.                 ;1、CPL小于等于调用门DPL;2、调用门选择子RPL小于等于调用门DPL。
  234.                 IF
  235.                         call gate DPL < CPL or call gate DPL < call gate segment-selector RPL
  236.                 THEN
  237.                         #GP(call gate selector); FI;

  238.                 ;检查2:
  239.                 ;如果调用门不存在
  240.                 ;引发异常。
  241.                 IF
  242.                         call gate not present
  243.                 THEN
  244.                         #NP(call gate selector); FI;

  245.                 ;检查3:
  246.                 ;如果调用门所调用代码段的选择子为空
  247.                 ;引发异常
  248.                 IF
  249.                         call gate code-segment selector is NULL
  250.                 THEN
  251.                         #GP(0); FI;

  252.                 ;检查4:
  253.                 ;如果调用门所调用代码段的选择子索引超出描述表的界限
  254.                 ;引发异常
  255.                 IF
  256.                         call gate code-segment selector index outside descriptor table limits
  257.                 THEN
  258.                         #GP(code segment selector); FI;
  259.                
  260.                 ;读取要调用的代码段的描述符
  261.                 Read code segment descriptor;
  262.                
  263.                 ;检查5:
  264.                 ;条件1:要调用的目标代码段段描述符不是指向一个代码段
  265.                 ;条件2:要调用的目标代码段是一致的且CPL小于DPL
  266.                 ;条件3:要调用的目标代码段是非一致的且CPL不等于DPL
  267.                 ;上述条件中有1个或1个以上成立,则引发异常
  268.                 IF
  269.                         code-segment segment descriptor does not indicate a code segment
  270.                         or code-segment segment descriptor is conforming and DPL > CPL
  271.                         or code-segment segment descriptor is non-conforming and DPL ≠ CPL
  272.                 THEN
  273.                         #GP(code segment selector); FI;
  274.                
  275.                 ;检查6:
  276.                 ;条件1:长模式处于激活状态
  277.                 ;条件2:代码段描述符指向的不是一个64位代码段
  278.                 ;条件3:代码段描述符L位和D位同时置1
  279.                 ;当条件1成立且条件2或者3中有1个或1个以上成立时,
  280.                 ;引发异常
  281.                 IF
  282.                         IA32_EFER.LMA = 1 and (code-segment descriptor is not a 64-bit code segment
  283.                         or code-segment segment descriptor has both L-Bit and D-bit set)
  284.                 THEN
  285.                         #GP(code segment selector); FI;
  286.                
  287.                 ;检查7
  288.                 ;如果代码段不存在
  289.                 ;引发异常
  290.                 IF
  291.                         code segment is not present
  292.                 THEN
  293.                         #NP(code-segment selector); FI;
  294.                
  295.                 ;检查8
  296.                 ;如果指令指针指向的指令不在代码段界限内
  297.                 ;引发异常
  298.                 IF
  299.                         instruction pointer is not within code-segment limit
  300.                 THEN
  301.                         #GP(0); FI;
  302.                
  303.                 ;上述所有检查都通过后,
  304.                 ;将目标操作数的偏移地址(偏移量)给临时EIP。
  305.                 tempEIP ← DEST(Offset);
  306.                
  307.                 ;如果操作数类型是16位的,
  308.                 ;则将32位临时偏移量的高16位清零
  309.                 IF
  310.                         GateSize = 16
  311.                 THEN
  312.                         tempEIP ← tempEIP AND 0000FFFFH; FI;
  313.                
  314.                 ;如果临时EIP数值超过代码段的界限
  315.                 ;并且长模式未激活、目标模式为兼容模式这两个条件有一个成立
  316.                 ;引发异常
  317.                 IF
  318.                         (IA32_EFER.LMA = 0 OR target mode = Compatibility mode) AND tempEIP outside code segment limit
  319.                 THEN
  320.                         #GP(0); FI
  321.                
  322.                 ;当上述检查全部通过
  323.                 ;则将目标段选择子加载到CS段选择器,段描述符的信息也加载到CS段选择器的不可见部分
  324.                 ;将当前指令的特权级数值写入CS段选择器的RPL部分
  325.                 ;将临时EIP数值传送给真正的EIP寄存器
  326.                 ;指令从新的CS:EIP处开始执行。
  327.                 ;第334行,可以看到跳转后的CPL仍是跳转前的CPL。
  328.                 CS ← DEST[SegmentSelector]; (* Segment descriptor information also loaded *)
  329.                 CS(RPL) ← CPL;
  330.                 EIP ← tempEIP;
  331.         END;

  332.         ;跳转到任务门
  333.         TASK-GATE:
  334.                
  335.                 ;检查1
  336.                 ;条件1:任务门描述符DPL小于CPL-表明当前特权级低于任务门描述符特权级
  337.                 ;条件2:任务门描述符DPL小于任务门选择子RPL-表明请求特权级低于任务门描述符特权级
  338.                 ;上述2个条件中有1个或者1个以上成立,则引发异常
  339.                 IF
  340.                         task gate DPL < CPL or task gate DPL < task gate segment-selector RPL
  341.                 THEN
  342.                         #GP(task gate selector); FI;

  343.                 ;检查2
  344.                 ;如果任务门不存在
  345.                 ;引发异常
  346.                 IF
  347.                         task gate not present
  348.                 THEN
  349.                         #NP(gate selector); FI;
  350.                
  351.                 ;读取任务门描述符中的TSS段选择子
  352.                 Read the TSS segment selector in the task-gate descriptor;
  353.                
  354.                 ;检查3
  355.                 ;条件1:TSS段选择子TI位被设置成1
  356.                 ;条件2:TSS段选择子的索引不在GDT界限内
  357.                 ;条件3:TSS描述符中的B位为1,处于忙的装填。
  358.                 ;上述3个条件中有1个或者1个以上条件成立,则引发异常。
  359.                 IF
  360.                         TSS segment selector local/global bit is set to local
  361.                         or index not within GDT limits
  362.                         or TSS descriptor specifies that the TSS is busy
  363.                 THEN
  364.                         #GP(TSS selector); FI;

  365.                 ;检查4
  366.                 ;如果TSS不存在
  367.                 ;引发异常
  368.                 IF
  369.                         TSS not present
  370.                 THEN
  371.                         #NP(TSS selector); FI;
  372.                
  373.                 ;转换任务到TSS
  374.                 SWITCH-TASKS to TSS;
  375.                
  376.                 ;检查5
  377.                 ;如果EIP指向的指令不在代码段界限内
  378.                 ;引发异常
  379.                 IF
  380.                         EIP not within code segment limit
  381.                 THEN
  382.                         #GP(0); FI;
  383.         END;

  384.         ;跳转到TSS
  385.         TASK-STATE-SEGMENT:
  386.                
  387.                 ;检查1
  388.                 ;条件1:TSS的DPL小于CPL-表明当前特权级低于TSS描述符特权级
  389.                 ;条件2:TSS的DPL小于TSS段选择子RPL-表明请求特权级低于TSS描述符特权级
  390.                 ;条件3:TSS描述符指向的TSS不是有效的
  391.                 ;上述3个条件中有1个或者1个以上条件成立,则引发异常。
  392.                 IF
  393.                         TSS DPL < CPL
  394.                         or TSS DPL < TSS segment-selector RPL
  395.                         or TSS descriptor indicates TSS not available
  396.                 THEN
  397.                         #GP(TSS selector); FI;
  398.                
  399.                 ;检查2
  400.                 ;如果TSS不存在
  401.                 ;引发异常。
  402.                 IF
  403.                         TSS is not present
  404.                 THEN
  405.                         #NP(TSS selector); FI;
  406.                
  407.                 ;切换任务
  408.                 SWITCH-TASKS to TSS;
  409.                
  410.                 ;检查3
  411.                 ;如果EIP指向的指令不在代码段界限内
  412.                 ;引发异常
  413.                 IF
  414.                         EIP not within code segment limit
  415.                 THEN
  416.                         #GP(0); FI;
  417.         END;

  418. Flags Affected(标志影响)
  419. All flags are affected if a task switch occurs; 如果发生任务切换,所有标志都会受到影响;
  420. no flags are affected if a task switch does not occur.;如果任务切换不发生,则不会影响任何标志。
复制代码





本帖被以下淘专辑推荐:

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2017-12-23 22:50:05 | 显示全部楼层
@人造人 我把几个资料相关资料翻译了一下,你看看,应该对理解特权级有帮助,这两天我再把CALL指令的远调用过程再发上来,就更加完善了。资料1、2、3都要一起看。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-12-23 22:59:30 | 显示全部楼层
兰陵月 发表于 2017-12-23 22:50
@人造人 我把几个资料相关资料翻译了一下,你看看,应该对理解特权级有帮助,这两天我再把CALL指令的远调用 ...

谢谢,这个对我应该会有用^_^

我目前正在从intel微处理器和bochs的源码中找答案,bochs是用C++写的,因此我现在正在学C++
^_^
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-4-26 13:47

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表