Assembling 16-Bit Code in a 32-Bit Code
®
Segment for Windows CE Bootstrap
Application Note
by Dave Tobias
This application note explains how to assemble 16-bit code in a 32-bit code segment for
Windows® CE bootstrap. This information is useful for those using a 32-bit microcontroller such as
an Élan™SC400 or ÉlanSC410 microcontroller.
The standard build process that comes with the OEM
adaptation kit for Windows CE requires that you use
the assembler in flat, 32-bit mode. However, the CPU
boots into 16-bit mode.
The two prefix bytes are 66h and 67h:
■ 66h changes the size of the instruction operand.
■ 67h changes the size of the instruction address.
Microsoft® compensates for this discrepancy by
keeping the 16-bit code as short as possible and also
by using macros to force the assembler into generating
instructions for 16-bit mode.
Separating the size of the operand from the size of the
address allows programmers to write instructions such
as the following:
mov ax, [ebx]
A good understanding of this workaround process is
required to successfully add chipset-specific
initialization code to the 16-bit code section.
In 16-bit mode, the assembler encodes the preceding
instruction as 67 8B 03. This is because the address
size is not the default 16 bits, so the assembler adds a
67h address prefix.
The execution unit of the CPU controls how the CPU
processes a given opcode. For a 386 (or later)
processor, the execution unit operates in either 16-bit
mode or 32-bit mode.
In 32-bit mode, the assembler encodes the instruction
as 66 8B 03. This is because the operand size is not
the default 32 bits, so the assembler adds a 66h
operand prefix.
The execution unit considers instruction size as two
elements: address size and data size. The execution
unit allows individual control over these two elements
on an instruction-by-instruction basis.
The assembler is designed to generate correct
prefixes. The programmer defines the mode in which
the assembler is operating by using the USE16 or
USE32 keyword in a segment definition.
When in real mode or V8086 mode, both the data and
address, which will be manipulated by a particular
opcode, default to being processed as 16-bit quantities
because descriptors are not used in real or V8086
modes.
Note that simply providing the assembler with one of
these directives does not control whether the CPU
hardware will actually operate in 16-bit mode or 32-bit
mode. This hardware setup must be done manually,
and is beyond the scope of this application note.
Specifying a USE16 or USE32 segment directive
simply tells the assembler to generate code as if the
CPU hardware is in 16-bit mode or 32-bit mode,
respectively.
When in protect mode, the default instruction size
depends on the default (D) bit, which is found in all
code segment descriptors, and which must be set up
by the systems programmer.
Regardless of whether the default instruction size is
16 bit or 32 bit, the execution unit can always execute
instructions using either 16-bit or 32-bit operands
and/or addresses. In fact, a given opcode can be
executed using any combination of operand size and
data size via the use of override prefix bytes. To
individually change the default address size and/or
default data size of a single instruction, either one or
two prefix bytes must precede the instruction.
Unfortunately, the assembler does not allow the
programmer to switch back and forth between these
assumptions in a single segment. NASM, the netwide
assembler, does allow this switching via the USE16
and USE32 assembler pseudo-operation codes.
(NASM is a free assembler available via the internet.)
The "clean" way to approach this problem if the
assembler does not support arbitrary switching
between USE16 and USE32 is to generate two
segments, a 16-bit segment and a 32-bit segment.
This document contains information on a product under development at Advanced Micro Devices. The information
is intended to help you evaluate this product. AMD reserves the right to change or discontinue work on this product
without notice.
Publication# 21642 Rev: A Amendment/0
Issue Date: November 1997