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