Vol. 3 18-3
MIXING 16-BIT AND 32-BIT CODE
These prefixes reverse the default size selected by the D flag in the code-segment
descriptor. For example, the processor can interpret the (MOV mem, reg) instruction
in any of four ways:
• In a 32-bit code segment:
— Moves 32 bits from a 32-bit register to memory using a 32-bit effective
address.
— If preceded by an operand-size prefix, moves 16 bits from a 16-bit register to
memory using a 32-bit effective address.
— If preceded by an address-size prefix, moves 32 bits from a 32-bit register to
memory using a 16-bit effective address.
— If preceded by both an address-size prefix and an operand-size prefix, moves
16 bits from a 16-bit register to memory using a 16-bit effective address.
• In a 16-bit code segment:
— Moves 16 bits from a 16-bit register to memory using a 16-bit effective
address.
— If preceded 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 IA-32 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 IA-32 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.