|
马上注册,结交更多好友,享用更多功能^_^
您需要 登录 才可以下载或查看,没有账号?立即注册
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.;如果任务切换不发生,则不会影响任何标志。
复制代码
|
|