background image

21-4 Vol. 3B

MIXING 16-BIT AND 32-BIT CODE

The size of the stack pointer (SP or ESP) changes when switching between 16-bit and 32-bit code segments.

These limitations are discussed in greater detail in the following sections.

21.4.1 

Code-Segment Pointer Size

For control-transfer instructions that use a pointer to identify the next instruction (that is, those that do not use 
gates), the operand-size attribute determines the size of the offset portion of the pointer. The implications of this 
rule are as follows:

A JMP, CALL, or RET instruction from a 32-bit segment to a 16-bit segment is always possible using a 32-bit 
operand size, providing the 32-bit pointer does not exceed FFFFH.

A JMP, CALL, or RET instruction from a 16-bit segment to a 32-bit segment cannot address a destination greater 
than FFFFH, unless the instruction is given an operand-size prefix.

See Section 21.4.5, “Writing Interface Procedures,” for an interface procedure that can transfer program control 
from 16-bit segments to destinations in 32-bit segments beyond FFFFH.

21.4.2 

Stack Management for Control Transfer

Because the stack is managed differently for 16-bit procedure calls than for 32-bit calls, the operand-size attribute 
of the RET instruction must match that of the CALL instruction (see Figure 21-1). On a 16-bit call, the processor 
pushes the contents of the 16-bit IP register and (for calls between privilege levels) the 16-bit SP register. The 
matching RET instruction must also use a 16-bit operand size to pop these 16-bit values from the stack into the 16-
bit registers. 
A 32-bit CALL instruction pushes the contents of the 32-bit EIP register and (for inter-privilege-level calls) the 32-
bit ESP register. Here, the matching RET instruction must use a 32-bit operand size to pop these 32-bit values from 
the stack into the 32-bit registers. If the two parts of a CALL/RET instruction pair do not have matching operand 
sizes, the stack will not be managed correctly and the values of the instruction pointer and stack pointer will not be 
restored to correct values.