These are legal instructions for 80386+. Starting with 80386, we can use the operandize- and addresssize-override prefixes. These prefixes can be used in conjunction with 16-bit address mode and 32-bit address mode. Additionally, it can be used with a real address module and with protected mode and virtual 86 mode. These prefixes change the default operand value and / or address for one instruction in the code. By default, operandize and addresssize are set using the D flag in the code segment descriptor (or if GDT / LDT is absent, then we become a 16-bit address moment after the completion of the POST biography process.)
In the 16-bit address module, we must add these prefixes if we want to use 32-bit operands and / or 32-bit addresses. Without these prefixes, we can only use 16-bit addresses / operands in 16-bit address mode.
With a 32-bit address module, we must leave these prefixes out of our code if we want to use 32-bit operands and / or 32-bit addresses. And if we add these prefixes to our code, then we can use 16-bit addresses / operands in 32-bit address mode.
Blockquote Intel:
An instruction prefix can be used to override the default operand size and code segment address size. These prefixes can be used both in real address mode and in protected mode and virtual 8086 mode. The prefix of the operand size or address size only changes the size for the duration of the instruction.
The following two instruction prefixes allow you to mix 32-bit and 16-bit operations in one segment: • Operand size prefix (66H) • Address size prefix (67H)
These prefixes change the default size selected by the D icon in the code segment descriptor. For example, a processor can interpret an instruction (MOV mem, reg) in any of four ways: • In a 32-bit code segment: -Keeps 32 bits from a 32-bit register into memory using a 32-bit effective address. - If it is preceded by a prefix of the size of the operand, it moves 16 bits from the 16-bit register to memory using the 32-bit effective address. -If it is prefixed with an address size prefix, it moves 32 bits from a 32-bit register to memory using a 16-bit effective address. - If the address size prefix and operand size prefix are transferred 16 bits from the 16-bit register to memory using the 16-bit effective address.
• In a 16-bit code segment: -Transmits 16 bits from a 16-bit register to memory using a 16-bit effective address. -If it is preceded by an operand-size prefix, it moves 32 bits from a 32-bit register to memory using a 16-bit effective address. - If it is preceded by an address size prefix, it moves 16 bits from a 16-bit register to memory using a 32-bit effective address. -If with an address size prefix and an operand size prefix, it is preceded by 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 a 16- or 32-bit default value for a code segment is usually based on the following criteria: • Performance. Always use 32-bit code segments whenever possible. They work much faster than 16-bit code segments on P6 family processors, and somewhat faster on earlier IA-32 processors. • The operating system will run on a code segment. If the operating system is a 16-bit operating system, it may not support 32-bit software modules. • Operating mode. If the code segment is designed to work in real-address mode, virtual 8086, or SMM mode, it must be a 16-bit code segment. • Backward compatible with earlier IA-32 processors. If the code segment must run on an Intel 8086 or Intel 286 processor, it must be a 16-bit code segment.
The D flag in the code segment descriptor specifies the operand size and default address size for code segment instructions. (In real address mode and virtual 8086 mode, which do not use segment descriptors, the default value is 16 bits.) The code segment with its set of flags D is a 32-bit segment; The code segment with its D-flag clearing is a 16-bit segment.
Segment of executable code. The flag is called the D flag and indicates the default length for effective addresses and operands referenced by instructions in the segment. If the flag is set, 32-bit addresses and 32-bit or 8-bit operands are assumed; if this is clear, it assumes 16-bit addresses and 16-bit or 8-bit operands. The 66H instruction prefix can be used to select an operand size other than the default, and the 67H prefix can be used to select an operand size other than the default.
The 32-bit operand prefix can be used in real-mode programs to execute 32-bit instruction forms. This prefix also allows real-time programs to use 32-bit universal processor registers. The 32-bit address prefix can be used in real-mode programs, allowing 32-bit offsets.
IA-32 processors, starting with the Intel386 processor, can generate 32-bit offsets using the address rewrite prefix; however, in real-address mode, the value of the 32-bit offset cannot exceed FFFFH without causing an exception.
Using assembler: If a segment of code that will run in real address mode is defined, it must be set to attribute USE 16. If a 32-bit operand is used in a command in this segment of code (for example, MOV EAX, EBX), the assembler automatically generates the operand prefix for a command that forces the processor to perform a 32-bit operation, even if its default code segment attribute is 16 bits.
The 32-bit operand prefix allows the real-time program to use 32-bit general-purpose registers (EAX, EBX, ECX, EDX, ESP, EBP, ESI, and EDI).
When moving data in 32-bit mode between a segment register and a 32-bit universal register, the Pentium Pro processor does not require the use of a 16-bit operand size prefix; however, some assemblers do require this prefix. The processor assumes that the 16 least significant bits of the universal register are the destination or source operand. When moving the value from the segment selector to the 32-bit register, the processor fills two high-order bytes in the register with zeros.
Blockquote AMD:
3.3.2. 32-bit and 16-bit addresses and operands The processor can be configured for 32-bit or 16-bit addresses and operand sizes. With 32-bit addresses and operands, the maximum linear address or segment offset is FFFFFFFFH (2 ^ 32-1), and operand sizes are usually 8 bits or 32 bits. With 16-bit addresses and operand sizes, the maximum linear address or segment offset is FFFFH (2 ^ 16-1), and the operand sizes are usually 8 bits or 16 bits. When using 32-bit addressing, the logical address (or far pointer) consists of a 16-bit segment selector and a 32-bit offset; when using 16-bit addressing, it consists of a 16-bit segment selector and a 16-bit offset. Instruction prefixes allow temporary redefinition of addresses and / or operands by default from within the program. When working in protected mode, the segment descriptor for the current executable code determines the default address and the size of the operand. A segment descriptor is a system data structure that is usually not visible to application code. Assembler directives allow you to use the addressing and size of the operands that will be selected for the program. Then, assembler and other tools for the segment descriptor for the code segment are installed accordingly. When working in real address mode, the address size and operand size are 16 bits by default. rewriting the address size can be used in real address mode to enable 32-bit addressing; However, the maximum allowable 32-bit linear address is still 000FFFFFH (2 ^ 20-1).
3.6. OPERATING DIMENSIONS AND ATTRIBUTES OF THE SIZE OF THE ADDRESS When the processor is running in protected mode, each code segment has the operand size of the default attribute and address size. These attributes are selected using the D (default size) flag in the segment descriptor for the code segment (see Chapter 3, "Protected Mode Memory" Guide, in the Intel Architecture Volume 3 Software Developer's Guide). When D is set, the 32-bit operand size and address size attributes are selected; when the flag is clear, attributes of size 16 bits are selected. When the processor runs in real address mode, virtual-8086 or SMM (System-Management-Mode), the operand size and address size attributes are always 16 bits by default. The operand size attribute selects the sizes of the operands in which the instructions operate. When the 16-bit operand size attribute is valid, the operands can usually be either 8 bits or 16 bits, and when the 32-bit operand size attribute is valid, the operands can usually be 8 bits or 32 bits. The address-size attribute selects the sizes of addresses used for address memory: 16 bits or 32 bits. When the 16-bit address size attribute is valid, the segment offsets and offsets are 16 bits. This restriction limits the size of a segment that can be addressed to 64 KB. When the 32-bit address size attribute is valid, the segment offsets and offsets are 32 bits, which allows segments up to 4 GB. The operand size attribute and address size attribute can be redefined for a specific one by adding the operand size and / or address prefix to the instruction (see "Instructions Prefixes" in Chapter 2 of the Intel Architecture Software Developers Guide, Volume 3). The effect of this prefix applies only to the instruction to which it is attached. Table 3-1 shows the effective operand size and address size (when executed in protected mode) depending on the settings of the D flag and prefixes of the operand size and address size.
Dirk