This preview shows page 1. Sign up to view the full content.
Unformatted text preview: by an operand-size prefix, moves 32 bits from a 32-bit register to memory using a 16-bit effective address. — If preceded by an address-size prefix, moves 16 bits from a 16-bit register to memory using a 32-bit effective address. — If preceded by both an address-size prefix and an operand-size prefix, moves 32 bits from a 32-bit register to memory using a 32-bit effective address. The previous examples show that any instruction can generate any combination of operand size and address size regardless of whether the instruction is in a 16- or 32-bit segment. The choice of the 16- or 32-bit default for a code segment is normally based on the following criteria: • • • • Performance—Always use 32-bit code segments when possible. They run much faster than 16-bit code segments on P6 family processors, and somewhat faster on earlier Intel Architecture processors. The operating system the code segment will be running on—If the operating system is a 16-bit operating system, it may not support 32-bit program modules. Mode of operation—If the code segment is being designed to run in real-address mode, virtual-8086 mode, or SMM, it must be a 16-bit code segment. Backward compatibility to earlier Intel Architecture processors—If a code segment must be able to run on an Intel 8086 or Intel 286 processor, it must be a 16-bit code segment. 17.3. SHARING DATA AMONG MIXED-SIZE CODE SEGMENTS
Data segments can be accessed from both 16-bit and 32-bit code segments. When a data segment that is larger than 64 KBytes is to be shared among 16- and 32-bit code segments, the data that is to be accessed from the 16-bit code segments must be located within the first 64 KBytes of the data segment. The reason for this is that 16-bit pointers by definition can only point to the first 64 KBytes of a segment. 17-3 MIXING 16-BIT AND 32-BIT CODE A stack that spans less than 64 KBytes can be shared by both 16- and 32-bit code segments. This class of stacks includes: • • • Stacks in expand-up segments with the G (granularity) and B (big) flags in the stacksegment descriptor clear. Stacks in expand-down segments with the G and B flags clear. Stacks in expand-up segments with the G flag set and the B flag clear and where the stack is contained completely within the lower 64 KBytes. (Offsets greater than FFFFH can be used for data, other than the stack, which is not shared.) Refer to Section 3.4.3., “Segment Descriptors” in Chapter 3, Protected-Mode Memory Management for a description of the G and B flags and the expand-down stack type. The B flag cannot, in general, be used to change the size of stack used by a 16-bit code segment. This flag controls the size of the stack pointer only for implicit stack references such as those caused by interrupts, exceptions, and the PUSH, POP, CALL, and RET instructions. It does not control explicit stack references, such as accesses to parameters or local variables. A 16-bit code segment can use a 32-bit stack only if the code is modified so that all explicit references to the stack are preceded by the 32-bit address-size prefix, causing those references to use 32-bit addressing and explicit writes to the stack pointer are preceded by a 32-bit operand-size prefix. In 32-bit, expand-down segments, all offsets may be greater than 64 KBytes; therefore, 16-bit code cannot use this kind of stack segment unless the code segment is modified to use 32-bit addressing. 17.4. TRANSFERRING CONTROL AMONG MIXED-SIZE CODE SEGMENTS
There are three ways for a procedure in a 16-bit code segment to safely make a call to a 32-bit code segment: • • • Make the call through a 32-bit call gate. Make a 16-bit call to a 32-bit interface procedure. The interface procedure then makes a 32-bit call to the intended destination. Modify the 16-bit procedure, inserting an operand-size prefix before the call, to change it to a 32-bit call. Likewise, there are three ways for procedure in a 32-bit code segment to safely make a call to a 16-bit code segment: • • • Make the call through a 16-bit call gate. Here, the EIP value at the CALL instruction cannot exceed FFFFH. Make a 32-bit call to a 16-bit interface procedure. The interface procedure then makes a 16-bit call to the intended destination. Modify the 32-bit procedure, inserting an operand-size prefix before the call, changing it to a 16-bit call. Be certain that the return offset does not exceed FFFFH. 17-4 MIXING 16-BIT AND 32-BIT CODE These methods of transferring program control overcome the following architectural limitations imposed on calls between 16-bit and 32-bit code segments: • • • • Pointers from 16-bit code segments (which by default can only be 16-bits) cannot be used to address data or code located beyond FFFFH in a 32-bit segment. The operand-size attributes for a CALL and its companion RETURN instruction must be the same to maintain stack coherency. This is also true for implicit calls to interrupt and exception handlers and their companion IRET instruc...
View Full Document
This note was uploaded on 06/07/2013 for the course ECE 1234 taught by Professor Kwhon during the Spring '10 term at University of California, Berkeley.
- Spring '10