PRB: MASM Generates Unexpected Prefix Bytes 66h, 67h (92611)
The information in this article applies to:
- Microsoft Macro Assembler (MASM) 5.0
- Microsoft Macro Assembler (MASM) 5.1
- Microsoft Macro Assembler (MASM) 5.1a
- Microsoft Macro Assembler (MASM) 6.0
- Microsoft Macro Assembler (MASM) 6.0a
- Microsoft Macro Assembler (MASM) 6.0b
This article was previously published under Q92611 SYMPTOMS
When the .386, .386p, .486, or .486p directive is used in MASM, the source
code listing or the mixed source and assembly code listing in the CodeView
debugger may indicate that code for 32-bit instructions has been generated
incorrectly. For example, when either of the following instructions is
assembled, the prefix bytes 66h and 67h may or may not appear before the
instruction opcode:
mov eax, [ebx]
mov ax, [bx]
CAUSE
The 386 and 486 processors can operate with either 32-bit operations or 16-
bit operations as the default mode. The descriptor for each memory segment
controls the default mode for operations in the segment. In either mode, a
prefix byte (66h or 67h) at the beginning of an instruction overrides the
default mode for the current memory segment for a given instruction. In
other words, when the processor encounters a prefix byte on an instruction
in a 16-bit segment, the instruction executes as a 32-bit operation.
The condition described above occurs when the source code indicates that a
code segment is a 16-bit segment or a 32-bit segment, and the segment
loaded into memory is of the opposite type.
RESOLUTION
When MASM assembles a file that uses full segment directives, it treats all
segments as 32-bit segments and all operations as 32-bit operations. To
change this treatment, specify the USE16 modifier for each SEGMENT
directive that describes a 16-bit segment. In MASM version 6.0 or later,
the OPTION SEGMENT:USE16 directive specifies that all segments are 16-bit
segments.
When MASM assembles a file that uses simplified segment declarations, it
treats all segments as 32-bit segments when a .386, .386p, .486, or .486p
processor directive precedes the .MODEL statement. If the processor
directive follows the .MODEL statement, MASM treats all segments as 16-bit
segments and all operations as 16-bit operations.
MORE INFORMATION
Note that to run code in 32-bit segments, the operating system with
which the application runs support 32-bit code segments. Most PC-based
operating systems, including MS-DOS version 5.0, Microsoft Windows
version 3.1, and OS/2 versions 1.x do not support 32-bit code
segments. Later versions of operating systems and MS-DOS extender
programs may provide this support.
For more information on the differences between 16-bit and 32-bit
segments, refer to chapter 16 of the "Intel 80386 Programmer's
Reference Manual" (1986 edition).
The following code samples demonstrate this problem when CodeView for
MS-DOS is used to debug these programs.
Sample Code
; Assembler options needed: /Zi
.386
DOSSEG ; Force DOS segment order
DGROUP GROUP _DATA, STACK ; Stack and data in DGROUP
STACK SEGMENT PARA STACK 'STACK'
DB 100h DUP (?) ; 256-byte stack
STACK ENDS
_DATA SEGMENT WORD PUBLIC 'DATA' ; Data segment with string data
msg DB "Hello, world.", 13, 10, "$"
_DATA ENDS
_TEXT SEGMENT WORD PUBLIC 'CODE' ; Code segment
ASSUME cs:_TEXT, ds:DGROUP, ss:DGROUP
start:
mov ax, DGROUP ; Initialize data segment
mov ds, ax
cli ; Turn off interrupts
mov ss, ax ; Make SS and
mov sp, OFFSET STACK ; SP relative to DGROUP
sti ; SS now equals DS
mov ah, 9h ; Request DOS Function 9
mov dx, OFFSET msg ; Load DX with offset of string
; (segment already in DS)
int 21h ; Display String to Standard Output
mov ax, 4C00h ; Exit functions with 0 in AL
int 21h ; Terminate Process with Return Code
_TEXT ENDS
END start ; End with reference to first
; executable statement (CS:IP)
Sample Code
; Assembler options needed: /Zi
.386
.MODEL small, c ; Small model (could be any model)
.STACK 100h ; 256-byte stack
.DATA ; Data segment
msg DB "Hello, world.", 13, 10, "$"
.CODE ; Code segment
start:
mov ax, DGROUP ; Initialize data segment
mov ds, ax
cli ; Turn off interrupts
mov ss, ax ; Make SS and
mov sp, OFFSET STACK ; SP relative to DGROUP
sti ; SS now equals DS
mov ah, 9h ; Request DOS Function 9
mov dx, OFFSET msg ; Load DX with offset of string
; (segment already in DS)
int 21h ; Display String to Standard Output
mov ax, 4C00h ; Exit functions with 0 in AL
int 21h ; Terminate Process with Return Code
END start ; End with reference to first
; executable statement (CS:IP)
Modification Type: | Major | Last Reviewed: | 10/17/2003 |
---|
Keywords: | KB92611 |
---|
|