Vol. 3 18-9
MIXING 16-BIT AND 32-BIT CODE

18.4.5 Writing Interface Procedures

Placing interface code between 32-bit and 16-bit procedures can be the solution to
the following interface problems:
Allowing procedures in 16-bit code segments to call procedures with offsets
greater than FFFFH in 32-bit code segments.
Matching operand-size attributes between companion CALL and RET instructions.
Translating parameters (data), including managing parameter strings with a
variable count or an odd number of 16-bit words.
The possible invalidation of the upper bits of the ESP register.
The interface procedure is simplified where these rules are followed.
1. The interface procedure must reside in a 32-bit code segment (the D flag for the
code-segment descriptor is set).
2. All procedures that may be called by 16-bit procedures must have offsets not
greater than FFFFH.
3. All return addresses saved by 16-bit procedures must have offsets not greater
than FFFFH.
The interface procedure becomes more complex if any of these rules are violated. For
example, if a 16-bit procedure calls a 32-bit procedure with an entry point beyond
FFFFH, the interface procedure will need to provide the offset to the entry point. The
mapping between 16- and 32-bit addresses is only performed automatically when a
call gate is used, because the gate descriptor for a call gate contains a 32-bit
address. When a call gate is not used, the interface code must provide the 32-bit
address.
The structure of the interface procedure depends on the types of calls it is going to
support, as follows:
Calls from 16-bit procedures to 32-bit procedures — Calls to the interface
procedure from a 16-bit code segment are made with 16-bit CALL instructions
(by default, because the D flag for the calling code-segment descriptor is clear),
and 16-bit operand-size prefixes are used with RET instructions to return from
the interface procedure to the calling procedure. Calls from the interface
procedure to 32-bit procedures are performed with 32-bit CALL instructions (by
default, because the D flag for the interface procedure’s code segment is set),
and returns from the called procedures to the interface procedure are performed
with 32-bit RET instructions (also by default).
Calls from 32-bit procedures to 16-bit procedures — Calls to the interface
procedure from a 32-bit code segment are made with 32-bit CALL instructions
(by default), and returns to the calling procedure from the interface procedure
are made with 32-bit RET instructions (also by default). Calls from the interface
procedure to 16-bit procedures require the CALL instructions to have the
operand-size prefixes, and returns from the called procedures to the interface
procedure are performed with 16-bit RET instructions (by default).