Use of the LTR and STR Instructions

General

The processor uses the TR (Task Register) to determine the base address and limit of the TSS associated with the current task. The TR is illustrated in Figure 10-6 on page 189.

Figure 10-6. The Task Register


Loading a new 16-bit value into the TR causes the processor to read the TSS descriptor from the GDT entry selected by the TR index field into the invisible part of the TR. When initially loaded with a 16-bit value, the processor uses that value to select an entry in the GDT (the selected entry must contain a TSS descriptor). If it contains any other type of descriptor, or if the selected TSS descriptor has its Busy bit set to one (more on the Busy bit in the next chapter), the processor generates a GP exception. A GP exception is also generated if the 16-bit value has TI = 1, selecting the LDT rather than the GDT.

The IA32 instruction set provides two instructions that the programmer can use to place a new value in the TR or to read the current value from it. The LTR (Load Task Register) and STR (Store Task Register) instructions may only be executed when the processor is in Protected Mode (CR0[PE] = 1). Attempted execution of either while in Real Mode results in an Invalid Opcode exception. The STR instruction can be executed at any privilege level, while the LTR instruction can only be executed by a program executing at privilege level zero. An attempt to execute the LTR instruction at any other privilege level results in a GP exception.

The STR Instruction

At any privilege level, the programmer may use the STR instruction to obtain (from the TR) the selector for the currently executing task's TSS descriptor in the GDT. The 16-bit value may be placed either into a 16-bit GPR or into memory. Using this value, the programmer can then read the TSS descriptor from the GDT to discover the base address and limit (i.e., the size of) the current task's TSS data structure.

The LTR Instruction

At privilege level zero, the programmer may execute the LTR instruction to place a new 16-bit value into the TR. When executed, the processor performs the following actions:

  • Validates that the current program's CPL is sufficiently-privileged to perform a task switch (since the CPL of the program executing the LTR instruction must be zero, this isn't a problem).

  • Generates a GP Exception if the indicated GDT entry does not contain a TSS descriptor or if the descriptor's Busy bit is set to one.

  • Generates a Segment Not Present Exception if P = 0 in the TSS descriptor.

  • Generates a Page Fault Exception if the page containing the TSS is not currently in memory.

  • Generates a GP exception if the CS selector in the TSS does not select a code segment.

  • Generates a GP exception if any of the data segment selectors in the TSS does not select a data segment.

  • Generates a Stack exception if the SS selector in the TSS doesn't select a stack segment (i.e., a read/writable data segment).

  • The invisible portion of the TR is loaded with the base address and limit of the new TSS.

  • The Busy bit in the TSS descriptor is set to one.

The LTR instruction does not cause a task switch. In other words, although the processor verifies the integrity of the new TSS and marks it busy, it does not reload its register set from the new TSS.

The TR contents after reset is undefined. This instruction is typically used at startup time to identify the OS code's startup TSS. If the TR were not initialized in this manner, the first task switch would cause the processor to save its register set into memory within the TSS identified by the bogus TSS base address and limit defined by the junk in the TR. In other words, the register set would be stored into some undefined region of memory. This could have catastrophic results.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.21.100.34