Compilation Tutorial: Control Transfer (2)

Source: Internet
Author: User

2. Note on instance three
The implementation of some steps has been introduced in the previous example, the following on the task of the transfer of no Privilege level transformation and the use of local descriptor Ldt and so on to make some notes:

(1) Initialization of LDT in real mode
The demo task uses a local descriptor LDT, which is initialized in real mode (and, of course, in the protected mode before using LDT) in this instance Ldt. For simplicity, the bounds and attribute values of each descriptor in the LDT are preset when defined, using a subroutine to set the Janki address of each segment. For convenience, segment values are arranged in the Janki address lower 16-bit field of the corresponding descriptor at the time of the definition. Because the segments in the instance are positioned in real mode (this is because the program starts executing in the actual mode), multiplying the segment value by 16 is the corresponding Janki address.

(2) Loading LDTR registers
Before using LDT, also load the local descriptor register LDTR. The following two directives in this example are used for loading LDTR:

MOV ax,ldt_sel Lldt ax
Lldt directives are instructions that are specifically used to load LDTR. The operand of the instruction is the selector of the corresponding LDT segment descriptor. According to the selector, the processor extracts the corresponding LDT segment descriptor from the GDT, and after checking the legality, the LDT segment descriptor's base address and the boundary information are loaded into the LDTR cache register. Because you are referencing GDT, you cannot load LDTR in real mode. The Lldt directive is described in detail in the "Operating system class directives" article.

(3) using the transfer instruction JMP to realize the transfer without privilege level in the task
After entering the protection mode in this instance, the privilege level is 0. The transfer from code snippet k to Code section L is implemented through direct transfer instruction between the following paragraphs:

JUMP16 Codel_sel,virtual2
Where the selector Codel_sel is the selector of the descriptor for the corresponding code segment L. The descriptor is in LDT, so the descriptor in the selector indicates that the bit TI is 1. The descriptor privilege level is 0, which means that the privileged level of the corresponding code snippet is 0, and the request privilege level in the RPL is also 0. The target code segment is not a consistent code segment, so in the case of CPL=DPL,RPL<=DPL, the transfer of the same privilege level is smooth: the selection of the target code segment Codel_sel is loaded into CS, the information in the corresponding descriptor is loaded into the buffer register, The offset Virtual2 is loaded into the instruction pointer register. Because it is a 16-bit code snippet, the offset is represented by 16 bits.
Similarly, transfers from the Code section l to the code snippet via the direct transfer instruction implementation between the following sections K:

JUMP16 Codek_sel,virtual3
Where the selector Codek_sel is the descriptor selector for the corresponding code segment K. Because the descriptor is in GDT, the TI bit in the selector is 0.

(4) The transfer of the non privileged level transformation in the task is realized by using the call instruction between paragraphs
In code snippet L, a direct invocation of command call between segments calls the two subroutines in code snippet C, which are transfers of no privilege level transformations. For example, the display string subroutine is invoked using the following directive dispmsg:

CALL16 codec_sel,dispmsg
Where Codec_sel is the selection of code snippet C, dispmsg represents the entry of the subroutine. Description of code snippet C in Ldt, the descriptor privilege level DPL is 0, so the selection of the selected child Codec_sel the request privilege level RPL is 0, the descriptor chart indicates that TI is 1. The target code segment C is not a consistent code segment, so in the case of CPL=DPL,RPL<=DPL, the same privilege level of transfer smoothly: the current CS and IP on the stack, the target code segment of the selection of Codec_sel is loaded into CS, the corresponding descriptor information is loaded into the cache register , the 16-bit offset dispmsg is loaded into the instruction pointer IP. Since it is a 16-bit segment, the offset is represented by 16-bit, and the stack is pressed into words instead of two words.

(5) Between paragraphs return instruction RET to realize the transfer of non privilege level transformation within a task
Deme returns the instruction ret to eject the return address (by selector and offset) from the top of the stack. Pop-up selection of the Rpl=cpl, and the corresponding DPL=CPL,RPL<=DPL is of course, so can smoothly carry out the same privilege level of transfer.

3. Alias Technology
In the above example three, two descriptors are used to describe the LDT segment of the demo task. The segment descriptor ldtable is arranged in the GDT, which is the system segment descriptor and describes the segment ldtseg as a local descriptor for the demo task Ldt. The descriptor Toldt is arranged in the LDT, which is a data segment descriptor that describes the segment ldtseg as a normal data segment. The descriptor ldtable is loaded into the LDTR, and the descriptor Toldt is loaded into a data segment register. Why do you do this? According to the functional requirements of instance three, you need to access the local Descriptor Chart LDT segment of the demo task to get the segment bounds of the code segment L, which needs to be done through a segment register, but you cannot load the selection of the system segment descriptor into the segment register, so use two descriptors to describe the segment ldtseg.
This technique is called Alias technology in order to satisfy the need to implement different modes of operation for the same segment, and the technology described by multiple descriptors. Alias technology is often used in the design of protection mode. For example, use two descriptors with different types of values to describe the same segment. Again, use two descriptors with different DPL to describe the same segment.

< three > different privilege level transformations within a task
There can be four privileged levels within a task, so transformations between different privilege levels are often occurring. For example, the outer application invokes routines of the inner operating system to obtain the necessary system services such as storage allocation. Once the internal operating system routines are complete, return to the outer application.

In the same task, the common way to implement the transformation from outer to inner layer of privilege level is to use call instruction between paragraphs to transfer the call gate, and the normal way to implement the privilege level from the inner layer to the outer layers is to use the return instruction of the paragraph to ret. Note that you cannot use the JMP instruction to implement different privilege level transformations within a task.

1. Transfer through the call door
The transfer of the call gate can be realized when the selector of the pointer in the instruction JMP and between paragraphs is called to call the gate descriptor. However, only the call instruction can be transformed to the inner level of privilege, and the jmp instruction can only be transferred to the sibling code.

The entry point of the call Gate descriptor transfer contains a 48-bit full pointer to the segment and offset of the destination address. When executing the command call between segments of the transfer instruction JMP or between segments through the task door, the selector within the instruction contains the pointer to determine the calling door, while the offset is discarded, and the 48-bit full pointer within the calling door is transferred as the target address pointer.

The processor Controls access to the portal descriptor using the same privilege level rules as the Access data segment. The DPL of the calling door descriptor provides the outermost privilege level to access the door, which is checked at a privileged level before removing the 48-bit full pointer in the calling door and transferring it as the target address pointer to the target code segment. Only programs in the same level or in the higher level of privilege can access the calling gate, that is, the DPL of the cpl<= call door. At the same time, it is also required that the RPL of the selector of the gate must satisfy the DPL condition of the rpl<= call gate. The steps to transfer to the target code fragment begin after the test passes. It also detects whether the target descriptor is a code snippet descriptor, and the selector within the calling door indicates that the descriptor must be a code snippet descriptor. In addition, the rpl=0 of the code snippet selector is adjusted before loading the code snippet Descriptor cache register, which means that the RPL of the code snippet selector in the calling door is ignored.


For the jmp transfer instruction using the call gate, the detection condition is the same as the direct transfer between the segments. Because the rpl=0 is already placed, the RPL<=DPL condition can be considered to be always satisfied. Therefore, for common inconsistent code segments, when CPL=DPL, there is no privilege level transformation, and for consistent code segments, there is no privilege-level transformation when satisfying cpl>=dpl, and other situations cause anomalies.

The situation is different for calling command calls between segments that use the calling door. Because the rpl=0 is already placed, the RPL<=DPL condition can be considered to be always satisfied. For consistent code segments, the transfer of a CPL>=DPL-level transformation occurs when a match is satisfied. For inconsistent code snippets, when CPL=DPL, the transfer of no privilege level transformation is still occurring, and when the CPL>DPL is transferred, the selector and the offset in the call gate are loaded into the CS and instruction pointer Eip, and the CPL remains equal to DPL and the inner stack is switched.

To sum up, using the command call between paragraphs, through the call door can be implemented from the outer program calls into the inner layer program (JMP instruction can only achieve the transfer of No Privilege level transformation), through the call gate can also achieve the transfer of no privilege level transformation. It should be noted that neither the JMP directive nor the call instruction can implement a transfer to the outer privilege level or cause an exception.

Of course, the call command at the end of the target Code section of the pointer into the CS and EIP, to the original CS and EIP, that is, return address to the stack. If no privilege level transformation, the stack remains unchanged, the return address is saved in the original stack, otherwise, the return address is saved in the inner stack.

2. Stack switch
When using the call instruction to move through the gate to the inner layer, not only does the privilege level change, the control shifts to a new code snippet, but also to the inner stack segment. The TSS format is visible from the Task status section in the fifth chapter of this tutorial, and TSS contains pointers to levels 0, 1, and Level 2 stacks. The SS and ESP registers are initialized by using the corresponding stack pointers in TSS to create an empty stack when the privilege level occurs to the inner layer transformation.

After the inner stack is established, the processor presses the value of the pointer SS and the ESP register of the outer stack into the inner stack, so that the corresponding return to the outer layer can restore the original outer stack. Then, copying the call arguments in two-word units from the outer stack into the inner stack, the DCount field value in the calling door determines the number of replication parameters. These copied parameters are the arguments that the main program passes through the stack to the subroutine, which is pressed into the outer stack before the call. By copying the parameters in the stack, the inner subroutine does not need to consider the switch of the stack, and easily accesses the arguments passed by the main program. Finally, the return address of the call is pressed onto the stack so that it returns at the end of the call. The following figure is a diagram of the inner stack, which copies 2 two-word parameters to the inner stack, from the outer stack, when transforming into an inner layer. Each item in the diagram is a double word, and the visible segment registers the selector to be expanded into 32 to be deposited on the stack, with a height of 16 bits 0. The same is true for 16-bit use of the calling door segment.

It is to be noted that the stack is not switched, regardless of whether or not the call door is passed, as long as the privilege level transformation does not occur.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.