Chapter 14   80386 Real-Address Mode

Chapter 14 80386 Real-Address Mode



Chapter 14  80386 Real-Address Mode

----------------------------------------------------------------------------

The real-address mode of the 80386 executes object code designed for
execution on 8086, 8088, 80186, or 80188 processors, or for execution in the
real-address mode of an 80286:

In effect, the architecture of the 80386 in this mode is almost identical
to that of the 8086, 8088, 80186, and 80188. To a programmer, an 80386 in
real-address mode appears as a high-speed 8086 with extensions to the
instruction set and registers. The principal features of this architecture
are defined in Chapters 2 and 3.

This chapter discusses certain additional topics that complete the system
programmer's view of the 80386 in real-address mode:

  *  Address formation.
  *  Extensions to registers and instructions.
  *  Interrupt and exception handling.
  *  Entering and leaving real-address mode.
  *  Real-address-mode exceptions.
  *  Differences from 8086.
  *  Differences from 80286 real-address mode.


14.1 Physical Address Formation

14.1 Physical Address Formation The 80386 provides a one Mbyte + 64 Kbyte memory space for an 8086 program. Segment relocation is performed as in the 8086: the 16-bit value in a segment selector is shifted left by four bits to form the base address of a segment. The effective address is extended with four high order zeros and added to the base to form a linear address as Figure 14-1 illustrates. (The linear address is equivalent to the physical address, because paging is not used in real-address mode.) Unlike the 8086, the resulting linear address may have up to 21 significant bits. There is a possibility of a carry when the base address is added to the effective address. On the 8086, the carried bit is truncated, whereas on the 80386 the carried bit is stored in bit position 20 of the linear address. Unlike the 8086 and 80286, 32-bit effective addresses can be generated (via the address-size prefix); however, the value of a 32-bit address may not exceed 65535 without causing an exception. For full compatibility with 80286 real-address mode, pseudo-protection faults (interrupt 12 or 13 with no error code) occur if an effective address is generated outside the range 0 through 65535. See Also:
Fig.14-1

14.2 Registers and Instructions

14.2 Registers and Instructions The register set available in real-address mode includes all the registers defined for the 8086 plus the new registers introduced by the 80386: FS, GS, debug registers, control registers, and test registers. New instructions that explicitly operate on the segment registers FS and GS are available, and the new segment-override prefixes can be used to cause instructions to utilize FS and GS for address calculations. Instructions can utilize 32-bit operands through the use of the operand size prefix. The instruction codes that cause undefined opcode traps (interrupt 6) include instructions of the protected mode that manipulate or interrogate 80386 selectors and descriptors; namely, VERR, VERW, LAR, LSL, LTR, STR, LLDT, and SLDT. Programs executing in real-address mode are able to take advantage of the new applications-oriented instructions added to the architecture by the introduction of the 80186/80188, 80286 and 80386: * New instructions introduced by 80186/80188 and 80286. -- PUSH immediate data -- Push all and pop all (PUSHA and POPA) -- Multiply immediate data -- Shift and rotate by immediate count -- String I/O -- ENTER and LEAVE -- BOUND * New instructions introduced by 80386. -- LSS, LFS, LGS instructions -- Long-displacement conditional jumps -- Single-bit instructions -- Bit scan -- Double-shift instructions -- Byte set on condition -- Move with sign/zero extension -- Generalized multiply -- MOV to and from control registers -- MOV to and from test registers -- MOV to and from debug registers

14.3 Interrupt and Exception Handling

14.3 Interrupt and Exception Handling Interrupts and exceptions in 80386 real-address mode work as much as they do on an 8086. Interrupts and exceptions vector to interrupt procedures via an interrupt table. The processor multiplies the interrupt or exception identifier by four to obtain an index into the interrupt table. The entries of the interrupt table are far pointers to the entry points of interrupt or exception handler procedures. When an interrupt occurs, the processor pushes the current values of CS:IP onto the stack, disables interrupts, clears TF (the single-step flag), then transfers control to the location specified in the interrupt table. An IRET instruction at the end of the handler procedure reverses these steps before returning control to the interrupted procedure. The primary difference in the interrupt handling of the 80386 compared to the 8086 is that the location and size of the interrupt table depend on the contents of the IDTR (IDT register). Ordinarily, this fact is not apparent to programmers, because, after RESET, the IDTR contains a base address of 0 and a limit of 3FFH, which is compatible with the 8086. However, the LIDT instruction can be used in real-address mode to change the base and limit values in the IDTR. Refer to Chapter 9 for details on the IDTR, and the LIDT and SIDT instructions. If an interrupt occurs and the corresponding entry of the interrupt table is beyond the limit stored in the IDTR, the processor raises exception 8.

14.4 Entering and Leaving Real-Address Mode

14.4 Entering and Leaving Real-Address Mode Real-address mode is in effect after a signal on the RESET pin. Even if the system is going to be used in protected mode, the start-up program will execute in real-address mode temporarily while initializing for protected mode.

14.4.1 Switching to Protected Mode

14.4.1 Switching to Protected Mode The only way to leave real-address mode is to switch to protected mode. The processor enters protected mode when a MOV to CR0 instruction sets the PE (protection enable) bit in CR0. (For compatibility with the 80286, the LMSW instruction may also be used to set the PE bit.) Refer to Chapter 10 "Initialization" for other aspects of switching to protected mode.

14.5 Switching Back to Real-Address Mode

14.5 Switching Back to Real-Address Mode The processor reenters real-address mode if software clears the PE bit in CR0 with a MOV to CR0 instruction. A procedure that attempts to do this, however, should proceed as follows: 1. If paging is enabled, perform the following sequence: * Transfer control to linear addresses that have an identity mapping; i.e., linear addresses equal physical addresses. * Clear the PG bit in CR0. * Move zeros to CR3 to clear out the paging cache. 2. Transfer control to a segment that has a limit of 64K (FFFFH). This loads the CS register with the limit it needs to have in real mode. 3. Load segment registers SS, DS, ES, FS, and GS with a selector that points to a descriptor containing the following values, which are appropriate to real mode: * Limit = 64K (FFFFH) * Byte granular (G = 0) * Expand up (E = 0) * Writable (W = 1) * Present (P = 1) * Base = any value 4. Disable interrupts. A CLI instruction disables INTR interrupts. NMIs can be disabled with external circuitry. 5. Clear the PE bit. 6. Jump to the real mode code to be executed using a far JMP. This action flushes the instruction queue and puts appropriate values in the access rights of the CS register. 7. Use the LIDT instruction to load the base and limit of the real-mode interrupt vector table. 8. Enable interrupts. 9. Load the segment registers as needed by the real-mode code.

14.6 Real-Address Mode Exceptions

14.6 Real-Address Mode Exceptions The 80386 reports some exceptions differently when executing in real-address mode than when executing in protected mode. Table 14-1 details the real-address-mode exceptions. See Also:
Tab.14-1

14.7 Differences from 8086

14.7 Differences From 8086 In general, the 80386 in real-address mode will correctly execute ROM-based software designed for the 8086, 8088, 80186, and 80188. Following is a list of the minor differences between 8086 execution on the 80386 and on an 8086. 1. Instruction clock counts. The 80386 takes fewer clocks for most instructions than the 8086/8088. The areas most likely to be affected are: * Delays required by I/O devices between I/O operations. * Assumed delays with 8086/8088 operating in parallel with an 8087. 2. Divide Exceptions Point to the DIV instruction. Divide exceptions on the 80386 always leave the saved CS:IP value pointing to the instruction that failed. On the 8086/8088, the CS:IP value points to the next instruction. 3. Undefined 8086/8088 opcodes. Opcodes that were not defined for the 8086/8088 will cause exception 6 or will execute one of the new instructions defined for the 80386. 4. Value written by PUSH SP. The 80386 pushes a different value on the stack for PUSH SP than the 8086/8088. The 80386 pushes the value of SP before SP is incremented as part of the push operation; the 8086/8088 pushes the value of SP after it is incremented. If the value pushed is important, replace PUSH SP instructions with the following three instructions: PUSH BP MOV BP, SP XCHG BP, [BP] This code functions as the 8086/8088 PUSH SP instruction on the 80386. 5. Shift or rotate by more than 31 bits. The 80386 masks all shift and rotate counts to the low-order five bits. This MOD 32 operation limits the count to a maximum of 31 bits, thereby limiting the time that interrupt response is delayed while the instruction is executing. 6. Redundant prefixes. The 80386 sets a limit of 15 bytes on instruction length. The only way to violate this limit is by putting redundant prefixes before an instruction. Exception 13 occurs if the limit on instruction length is violated. The 8086/8088 has no instruction length limit. 7. Operand crossing offset 0 or 65,535. On the 8086, an attempt to access a memory operand that crosses offset 65,535 (e.g., MOV a word to offset 65,535) or offset 0 (e.g., PUSH a word when SP = 1) causes the offset to wrap around modulo 65,536. The 80386 raises an exception in these cases--exception 13 if the segment is a data segment (i.e., if CS, DS, ES, FS, or GS is being used to address the segment), exception 12 if the segment is a stack segment (i.e., if SS is being used). 8. Sequential execution across offset 65,535. On the 8086, if sequential execution of instructions proceeds past offset 65,535, the processor fetches the next instruction byte from offset 0 of the same segment. On the 80386, the processor raises exception 13 in such a case. 9. LOCK is restricted to certain instructions. The LOCK prefix and its corresponding output signal should only be used to prevent other bus masters from interrupting a data movement operation. The 80386 always asserts the LOCK signal during an XCHG instruction with memory (even if the LOCK prefix is not used). LOCK may only be used with the following 80386 instructions when they update memory: BTS, BTR, BTC, XCHG, ADD, ADC, SUB, SBB, INC, DEC, AND, OR, XOR, NOT, and NEG. An undefined-opcode exception (interrupt 6) results from using LOCK before any other instruction. 10. Single-stepping external interrupt handlers. The priority of the 80386 single-step exception is different from that of the 8086/8088. The change prevents an external interrupt handler from being single-stepped if the interrupt occurs while a program is being single-stepped. The 80386 single-step exception has higher priority that any external interrupt. The 80386 will still single-step through an interrupt handler invoked by the INT instructions or by an exception. 11. IDIV exceptions for quotients of 80H or 8000H. The 80386 can generate the largest negative number as a quotient for the IDIV instruction. The 8086/8088 causes exception zero instead. 12. Flags in stack. The setting of the flags stored by PUSHF, by interrupts, and by exceptions is different from that stored by the 8086 in bit positions 12 through 15. On the 8086 these bits are stored as ones, but in 80386 real-address mode bit 15 is always zero, and bits 14 through 12 reflect the last value loaded into them. 13. NMI interrupting NMI handlers. After an NMI is recognized on the 80386, the NMI interrupt is masked until an IRET instruction is executed. 14. Coprocessor errors vector to interrupt 16. Any 80386 system with a coprocessor must use interrupt vector 16 for the coprocessor error exception. If an 8086/8088 system uses another vector for the 8087 interrupt, both vectors should point to the coprocessor-error exception handler. 15. Numeric exception handlers should allow prefixes. On the 80386, the value of CS:IP saved for coprocessor exceptions points at any prefixes before an ESC instruction. On 8086/8088 systems, the saved CS:IP points to the ESC instruction. 16. Coprocessor does not use interrupt controller. The coprocessor error signal to the 80386 does not pass through an interrupt controller (an 8087 INT signal does). Some instructions in a coprocessor error handler may need to be deleted if they deal with the interrupt controller. 17. Six new interrupt vectors. The 80386 adds six exceptions that arise only if the 8086 program has a hidden bug. It is recommended that exception handlers be added that treat these exceptions as invalid operations. This additional software does not significantly affect the existing 8086 software because the interrupts do not normally occur. These interrupt identifiers should not already have been used by the 8086 software, because they are in the range reserved by Intel. Table 14-2 describes the new 80386 exceptions. 18. One megabyte wraparound. The 80386 does not wrap addresses at 1 megabyte in real-address mode. On members of the 8086 family, it possible to specify addresses greater than one megabyte. For example, with a selector value 0FFFFH and an offset of 0FFFFH, the effective address would be 10FFEFH (1 Mbyte + 65519). The 8086, which can form adresses only up to 20 bits long, truncates the high-order bit, thereby "wrapping" this address to 0FFEFH. However, the 80386, which can form addresses up to 32 bits long does not truncate such an address. See Also:
Tab.14-2 Tab.14-1

14.8 Differences from 80286 Real-Address Mode

14.8 Differences From 80286 Real-Address Mode The few differences that exist between 80386 real-address mode and 80286 real-address mode are not likely to affect any existing 80286 programs except possibly the system initialization procedures.

14.8.1 Bus Lock

14.8.1 Bus Lock The 80286 processor implements the bus lock function differently than the 80386. Programs that use forms of memory locking specific to the 80286 may not execute properly if transported to a specific application of the 80386. The LOCK prefix and its corresponding output signal should only be used to prevent other bus masters from interrupting a data movement operation. LOCK may only be used with the following 80386 instructions when they modify memory. An undefined-opcode exception results from using LOCK before any other instruction. * Bit test and change: BTS, BTR, BTC. * Exchange: XCHG. * One-operand arithmetic and logical: INC, DEC, NOT, and NEG. * Two-operand arithmetic and logical: ADD, ADC, SUB, SBB, AND, OR, XOR. A locked instruction is guaranteed to lock only the area of memory defined by the destination operand, but may lock a larger memory area. For example, typical 8086 and 80286 configurations lock the entire physical memory space. With the 80386, the defined area of memory is guranteed to be locked against access by a processor executing a locked instruction on exactly the same memory area, i.e., an operand with identical starting address and identical length.

14.8.2 Location of First Instruction

14.8.2 Location of First Instruction The starting location is 0FFFFFFF0H (sixteen bytes from end of 32-bit address space) on the 80386 rather than 0FFFFF0H (sixteen bytes from end of 24-bit address space) as on the 80286. Many 80286 ROM initialization programs will work correctly in this new environment. Others can be made to work correctly with external hardware that redefines the signals on A{31-20}.

14.8.3 Initial Values of General Registers

14.8.3 Initial Values of General Registers On the 80386, certain general registers may contain different values after RESET than on the 80286. This should not cause compatibility problems, because the content of 8086 registers after RESET is undefined. If self-test is requested during the reset sequence and errors are detected in the 80386 unit, EAX will contain a nonzero value. EDX contains the component and revision identifier. Refer to Chapter 10 for more information.

14.8.4 MSW Initialization

14.8.4 MSW Initialization The 80286 initializes the MSW register to FFF0H, but the 80386 initializes this register to 0000H. This difference should have no effect, because the bits that are different are undefined on the 80286. Programs that read the value of the MSW will behave differently on the 80386 only if they depend on the setting of the undefined, high-order bits.