3. Note on instance Four
The background and implementation methods of partial fragments in the program are described in the previous example, the following is mainly on how to implement the task of the privilege level transformation to do some explaining:
(1) Implementation of Privilege level transformation through the return instruction between segments
The instance uses the return instruction between paragraphs to implement the privilege level transformation within the task. One is a demo snippet with a 0-level transition code segment that uses a RET instruction from the privilege level 0 to the privilege Level 3. The RET instruction does not correspond to the call instruction. The instance cpl=0 after switching to protection mode from the actual mode. To demonstrate how to invoke the inner program by calling the door, try to make the cpl>0. To that end, an instance builds an already occurring environment from the outer layer to the inner layer, that is, the pointer to the outer stack in the current stack (level 0 stack), and the entry pointer of the outer presentation program, to form a level 0 stack as shown in the figure below, without passing parameters. Then, the execution segment returns the instruction ret, pops the rpl=3 of the Level 3 demo code snippet from the stack, and then cpl=0, resulting in the transformation of the privilege level to the outer layer, from the Level 0 transition code segment to the Level 3 demo snippet, while switching to the level 3 stack.
The other is a 1-level display subroutine Echosub returned to level 3 of the demo program segment. The RET instruction in the service corresponds to call instruction called between the sections of the calling gate used in the demo program, and the level 1 stack of the return instruction ret between the execution segments is also shown in the figure above, where the return address and the outer stack pointer are pressed in by the call instruction.
(2) Realization of Privilege level transformation by calling Gate
The instance uses the inter-paragraph invocation instruction in two places, and implements the privilege-level transformation by calling the gate. A Level 3 demo code invokes a level 1 display subroutine by calling the door toechogate. The call door toechogate its own dpl=3, only so that the 3-level demo code can use the calling door. Because the selector inside the call door Echo_sel3 the display subroutine code snippet descriptor dpl=1, and then cpl=3, it causes a transformation from the outer privilege level to the inner layer privilege level so that cpl=1. The 1-level stack is also formed as shown above. Although the rpl=3 of the selector echo_sel3 within the call gate is greater than the DPL of the target code segment, it does not matter, because when the gate is transferred through the call door, the selector rpl that indicates the target code segment is always treated 0.
The other is a Level 3 demo code that also invokes a level 0 transition code by calling the door tot32gateb. The call gate descriptor used at the DPL is also equal to 3. Because the selector inside the call gate T32code_sel the dpl=0 of the Transition Code snippet descriptor, and then cpl=3, it causes the transformation from 3 privilege level to 0 privilege level to make cpl=0. The 0-level stack is also formed as shown above. But the call is actually "there goes no back", the purpose of the call is to move to level 0 of the transition code, ready to return to real mode. Because of the privilege level transformation of the transition code from level 3 demo code to level 0, you cannot use the transfer instruction JMP, you must use call instruction.
(3) Implementation of no privilege level transformation through the call gate
In the temporary code snippet, use the call gate Tot32gatea to transfer to the transition code snippet. The privilege-level transformation does not occur, although the dpl=0 of the Transition code snippet descriptor indicated by the selector T32code_sel in the door is cpl=0. It is for this reason that the jmp transfer instruction can be used.
(4) Implementation of subroutine Echosub
The function of the subroutine Echosub is to display the privilege level when the calling program executes. The execution privilege level of the caller selects the RPL field of the child within the code snippet Register CS, and when the echosub is invoked, the contents of the CS register are pressed onto the stack. The subroutine obtains the calling program's code snippet selector from the stack, and then separates the RPL from the calling program's execution privilege level.
(5) Load task status segment register TR
When a privilege level transformation occurs within a task, the stack is also automatically switched, the outer stack pointer is saved in the inner stack, and the inner stack pointer is stored in the TSS of the current task. Therefore, when transforming from the outer layer to the inner layers, it is necessary to access TSS (no TSS is required to transfer from the inner layer to the outer layers, but only the stack pointers stored in the inner stack). After the instance has entered the temporary code snippet in protected mode, the task state Segment register TR is loaded with the following two instructions to point to the TSS of the preset task:
mov ax,DemoTSS_Sel ltr ax
The LTR directive is an instruction specifically for loading the task state Segment register TR. The operand of the instruction is the selector of the TSS segment descriptor. The ltr instruction extracts the corresponding TSS segment descriptor from the GDT and loads the base address and bounds of the TSS segment descriptor into a TR cache register.