background image

21-6 Vol. 3B

MIXING 16-BIT AND 32-BIT CODE

be stored in 32-bit format. If the call is to a 32-bit code segment, the instructions in that code segment will be able 
to read the stack coherently. Also, a RET instruction from the 32-bit code segment without an operand-size prefix 
will maintain stack coherency with the 16-bit code segment being returned to.
When a CALL instruction references a call-gate descriptor, the type of call is determined by the type of call gate (16-
bit or 32-bit). The offset to the destination in the code segment being called is taken from the gate descriptor; 
therefore, if a 32-bit call gate is used, a procedure in a 16-bit code segment can call a procedure located more than 
64 KBytes from the base of a 32-bit code segment, because a 32-bit call gate uses a 32-bit offset.
Note that regardless of the operand size of the call and how it is determined, the size of the stack pointer used (SP 
or ESP) is always controlled by the B flag in the stack-segment descriptor currently in use (that is, when B is clear, 
SP is used, and when B is set, ESP is used).
An unmodified 16-bit code segment that has run successfully on an 8086 processor or in real-mode on a later IA-
32 architecture processor will have its D flag clear and will not use operand-size override prefixes. As a result, all 
CALL instructions in this code segment will use the 16-bit operand-size attribute. Procedures in these code 
segments can be modified to safely call procedures to 32-bit code segments in either of two ways:

Relink the CALL instruction to point to 32-bit call gates (see Section 21.4.2.2, “Passing Parameters With a 
Gate”).

Add a 32-bit operand-size prefix to each CALL instruction.

21.4.2.2   Passing Parameters With a Gate

When referencing 32-bit gates with 16-bit procedures, it is important to consider the number of parameters passed 
in each procedure call. The count field of the gate descriptor specifies the size of the parameter string to copy from 
the current stack to the stack of a more privileged (numerically lower privilege level) procedure. The count field of 
a 16-bit gate specifies the number of 16-bit words to be copied, whereas the count field of a 32-bit gate specifies 
the number of 32-bit doublewords to be copied. The count field for a 32-bit gate must thus be half the size of the 
number of words being placed on the stack by a 16-bit procedure. Also, the 16-bit procedure must use an even 
number of words as parameters.

21.4.3 

Interrupt Control Transfers

A program-control transfer caused by an exception or interrupt is always carried out through an interrupt or trap 
gate (located in the IDT). Here, the type of the gate (16-bit or 32-bit) determines the operand-size attribute used 
in the implicit call to the exception or interrupt handler procedure in another code segment.
A 32-bit interrupt or trap gate provides a safe interface to a 32-bit exception or interrupt handler when the excep-
tion or interrupt occurs in either a 32-bit or a 16-bit code segment. It is sometimes impractical, however, to place 
exception or interrupt handlers in 16-bit code segments, because only 16-bit return addresses are saved on the 
stack. If an exception or interrupt occurs in a 32-bit code segment when the EIP was greater than FFFFH, the 16-
bit handler procedure cannot provide the correct return address.

21.4.4 Parameter 

Translation

When segment offsets or pointers (which contain segment offsets) are passed as parameters between 16-bit and 
32-bit procedures, some translation is required. If a 32-bit procedure passes a pointer to data located beyond 64 
KBytes to a 16-bit procedure, the 16-bit procedure cannot use it. Except for this limitation, interface code can 
perform any format conversion between 32-bit and 16-bit pointers that may be needed.
Parameters passed by value between 32-bit and 16-bit code also may require translation between 32-bit and 16-
bit formats. The form of the translation is application-dependent.

21.4.5 

Writing Interface Procedures

Placing interface code between 32-bit and 16-bit procedures can be the solution to the following interface prob-
lems: