Volume 2A Instruction Set Reference A-M (794101), страница 92
Текст из файла (страница 92)
The new codesegment selector and its descriptor are loaded into CS register, and the offset fromthe instruction is loaded into the EIP register. Note that a call gate (described in thenext paragraph) can also be used to perform far call to a code segment at the sameprivilege level. Using this mechanism provides an extra level of indirection and is thepreferred method of making jumps between 16-bit and 32-bit code segments.When executing a far jump through a call gate, the segment selector specified by thetarget operand identifies the call gate. (The offset part of the target operand isignored.) The processor then jumps to the code segment specified in the call gatedescriptor and begins executing the instruction at the offset specified in the call gate.No stack switch occurs.
Here again, the target operand can specify the far address ofthe call gate either directly with a pointer (ptr16:16 or ptr16:32) or indirectly with amemory location (m16:16 or m16:32).Executing a task switch with the JMP instruction is somewhat similar to executing ajump through a call gate. Here the target operand specifies the segment selector ofthe task gate for the task being switched to (and the offset part of the target operandis ignored).
The task gate in turn points to the TSS for the task, which contains thesegment selectors for the task’s code and stack segments. The TSS also contains theEIP value for the next instruction that was to be executed before the task wassuspended. This instruction pointer value is loaded into the EIP register so that thetask begins executing again at this next instruction.JMP—JumpVol. 2A 3-573INSTRUCTION SET REFERENCE, A-MThe JMP instruction can also specify the segment selector of the TSS directly, whicheliminates the indirection of the task gate. See Chapter 7 in Intel® 64 and IA-32Architectures Software Developer’s Manual, Volume 3A, for detailed information onthe mechanics of a task switch.Note that when you execute at task switch with a JMP instruction, the nested taskflag (NT) is not set in the EFLAGS register and the new TSS’s previous task link fieldis not loaded with the old task’s TSS selector.
A return to the previous task can thusnot be carried out by executing the IRET instruction. Switching tasks with the JMPinstruction differs in this regard from the CALL instruction which does set the NT flagand save the previous task link information, allowing a return to the calling task withan IRET instruction.In 64-Bit Mode — The instruction’s operation size is fixed at 64 bits. If a selectorpoints to a gate, then RIP equals the 64-bit displacement taken from gate; else RIPequals the zero-extended offset from the far pointer referenced in the instruction.See the summary chart at the beginning of this section for encoding data and limits.OperationIF near jumpIF 64-bit ModeTHENIF near relative jumpTHENtempRIP ← RIP + DEST; (* RIP is instruction following JMP instruction*)ELSE (* Near absolute jump *)tempRIP ← DEST;FI:ELSEIF near relative jumpTHENtempEIP ← EIP + DEST; (* EIP is instruction following JMP instruction*)ELSE (* Near absolute jump *)tempEIP ← DEST;FI:FI;IF (IA32_EFER.LMA = 0 or target mode = Compatibility mode)and tempEIP outside code segment limitTHEN #GP(0); FIIF 64-bit mode and tempRIP is not canonicalTHEN #GP(0);FI;IF OperandSize = 32THENEIP ← tempEIP;3-574 Vol.
2AJMP—JumpINSTRUCTION SET REFERENCE, A-MELSEIF OperandSize = 16THEN (* OperandSize = 16 *)EIP ← tempEIP AND 0000FFFFH;ELSE (* OperandSize = 64)RIP ← tempRIP;FI;FI;FI;IF far jump and (PE = 0 or (PE = 1 AND VM = 1)) (* Real-address or virtual-8086 mode *)THENtempEIP ← DEST(Offset); (* DEST is ptr16:32 or [m16:32] *)IF tempEIP is beyond code segment limitTHEN #GP(0); FI;CS ← DEST(segment selector); (* DEST is ptr16:32 or [m16:32] *)IF OperandSize = 32THENEIP ← tempEIP; (* DEST is ptr16:32 or [m16:32] *)ELSE (* OperandSize = 16 *)EIP ← tempEIP AND 0000FFFFH; (* Clear upper 16 bits *)FI;FI;IF far jump and (PE = 1 and VM = 0)(* IA-32e mode or protected mode, not virtual-8086 mode *)THENIF effective address in the CS, DS, ES, FS, GS, or SS segment is illegalor segment selector in target operand NULLTHEN #GP(0); FI;IF segment selector index not within descriptor table limitsTHEN #GP(new selector); FI;Read type and access rights of segment descriptor;IF (EFER.LMA = 0)THENIF segment type is not a conforming or nonconforming codesegment, call gate, task gate, or TSSTHEN #GP(segment selector); FI;ELSEIF segment type is not a conforming or nonconforming code segmentcall gateTHEN #GP(segment selector); FI;FI;Depending on type and access rights:GO TO CONFORMING-CODE-SEGMENT;GO TO NONCONFORMING-CODE-SEGMENT;JMP—JumpVol.
2A 3-575INSTRUCTION SET REFERENCE, A-MGO TO CALL-GATE;GO TO TASK-GATE;GO TO TASK-STATE-SEGMENT;ELSE#GP(segment selector);FI;CONFORMING-CODE-SEGMENT:IF L-Bit = 1 and D-BIT = 1 and IA32_EFER.LMA = 1THEN GP(new code segment selector); FI;IF DPL > CPLTHEN #GP(segment selector); FI;IF segment not presentTHEN #NP(segment selector); FI;tempEIP ← DEST(Offset);IF OperandSize = 16THEN tempEIP ← tempEIP AND 0000FFFFH;FI;IF (IA32_EFER.LMA = 0 or target mode = Compatibility mode) andtempEIP outside code segment limitTHEN #GP(0); FIIF tempEIP is non-canonicalTHEN #GP(0); FI;CS ← DEST[segment selector]; (* Segment descriptor information also loaded *)CS(RPL) ← CPLEIP ← tempEIP;END;NONCONFORMING-CODE-SEGMENT:IF L-Bit = 1 and D-BIT = 1 and IA32_EFER.LMA = 1THEN GP(new code segment selector); FI;IF (RPL > CPL) OR (DPL ≠ CPL)THEN #GP(code segment selector); FI;IF segment not presentTHEN #NP(segment selector); FI;tempEIP ← DEST(Offset);IF OperandSize = 16THEN tempEIP ← tempEIP AND 0000FFFFH; FI;IF (IA32_EFER.LMA = 0 OR target mode = Compatibility mode)and tempEIP outside code segment limitTHEN #GP(0); FIIF tempEIP is non-canonical THEN #GP(0); FI;CS ← DEST[segment selector]; (* Segment descriptor information also loaded *)CS(RPL) ← CPL;EIP ← tempEIP;END;3-576 Vol.
2AJMP—JumpINSTRUCTION SET REFERENCE, A-MCALL-GATE:IF call gate DPL < CPLor call gate DPL < call gate segment-selector RPLTHEN #GP(call gate selector); FI;IF call gate not presentTHEN #NP(call gate selector); FI;IF call gate code-segment selector is NULLTHEN #GP(0); FI;IF call gate code-segment selector index outside descriptor table limitsTHEN #GP(code segment selector); FI;Read code segment descriptor;IF code-segment segment descriptor does not indicate a code segmentor code-segment segment descriptor is conforming and DPL > CPLor code-segment segment descriptor is non-conforming and DPL ≠ CPLTHEN #GP(code segment selector); FI;IF IA32_EFER.LMA = 1 and (code-segment descriptor is not a 64-bit code segmentor code-segment segment descriptor has both L-Bit and D-bit set)THEN #GP(code segment selector); FI;IF code segment is not presentTHEN #NP(code-segment selector); FI;IF instruction pointer is not within code-segment limitTHEN #GP(0); FI;tempEIP ← DEST(Offset);IF GateSize = 16THEN tempEIP ← tempEIP AND 0000FFFFH; FI;IF (IA32_EFER.LMA = 0 OR target mode = Compatibility mode) AND tempEIPoutside code segment limitTHEN #GP(0); FICS ← DEST[SegmentSelector); (* Segment descriptor information also loaded *)CS(RPL) ← CPL;EIP ← tempEIP;END;TASK-GATE:IF task gate DPL < CPLor task gate DPL < task gate segment-selector RPLTHEN #GP(task gate selector); FI;IF task gate not presentTHEN #NP(gate selector); FI;Read the TSS segment selector in the task-gate descriptor;IF TSS segment selector local/global bit is set to localor index not within GDT limitsor TSS descriptor specifies that the TSS is busyTHEN #GP(TSS selector); FI;JMP—JumpVol.
2A 3-577INSTRUCTION SET REFERENCE, A-MIF TSS not presentTHEN #NP(TSS selector); FI;SWITCH-TASKS to TSS;IF EIP not within code segment limitTHEN #GP(0); FI;END;TASK-STATE-SEGMENT:IF TSS DPL < CPLor TSS DPL < TSS segment-selector RPLor TSS descriptor indicates TSS not availableTHEN #GP(TSS selector); FI;IF TSS is not presentTHEN #NP(TSS selector); FI;SWITCH-TASKS to TSS;IF EIP not within code segment limitTHEN #GP(0); FI;END;Flags AffectedAll flags are affected if a task switch occurs; no flags are affected if a task switch doesnot occur.Protected Mode Exceptions#GP(0)If offset in target operand, call gate, or TSS is beyond the codesegment limits.If the segment selector in the destination operand, call gate,task gate, or TSS is NULL.If a memory operand effective address is outside the CS, DS,ES, FS, or GS segment limit.If the DS, ES, FS, or GS register is used to access memory and itcontains a NULL segment selector.#GP(selector)If the segment selector index is outside descriptor table limits.If the segment descriptor pointed to by the segment selector inthe destination operand is not for a conforming-code segment,nonconforming-code segment, call gate, task gate, or task statesegment.If the DPL for a nonconforming-code segment is not equal to theCPL(When not using a call gate.) If the RPL for the segment’ssegment selector is greater than the CPL.If the DPL for a conforming-code segment is greater than theCPL.3-578 Vol.