鱼C论坛

 找回密码
 立即注册
查看: 3644|回复: 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.如果任务切换不发生,则不会影响任何标志。



                               
登录/注册后可看大图

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


                               
登录/注册后可看大图

                               
登录/注册后可看大图
        
        ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
        ;;;;;;;;;;下面为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。
                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。
                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。
                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.;如果任务切换不发生,则不会影响任何标志。




本帖被以下淘专辑推荐:

想知道小甲鱼最近在做啥?请访问 -> 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-11-25 00:10

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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