disassembler prefix-byte check -- wanting comments good and bad

From: Bx.C (invalid-email-address_at_invalid.shiragajin)
Date: 03/26/04


Date: Fri, 26 Mar 2004 03:24:50 +0000 (UTC)

i'm looking for any and all comments i can get regarding the code snippet
below (other than the 32-bit vs 16-bit argument... i'll be making a 32-bit
version... somewhere in the future...

every bit in the word [prefix_flags] has special meaning to this code...
check the description down at the very bottom of the snippet if things get
confusing... please try to find any and all possible bugs that you can....
naturally this code will be reading unknown data, so i want to be certain
that all possible byte combinations have been considered for this code
snippet...

....i'm thinking of throwing in a check, to see if BX=0000Eh before
incrementing again... this is because you can only have a maximum of 14
prefix bytes (considering multiple prefix bytes here)... as the 15th byte
has to be an opcode byte,... if it's another prefix byte then you get #UD...
so i'm trying to figure out how I want to handle this situation... please
give any and all possible ideas for this....

ANYWAYS.... here's the code...

NOTE: This is a code SNIPPET... this isn't a 100% fully functional,
stand-alone piece of code... i've documented the entering and exiting
register values in case anyone wants to wrap it to test... if you do..
please make sure that [prefix_flags] is updated correctly.... if two or more
segment overrides are found or two or more rep prefixes are found, bit 3
gets set, so the program using this snippet can alert the user to POSSIBLE
system-dependent action... ie. some processors will act differently than
others... i have written code that'll detect and initialize [prefix_flags]
accordingly, but that code isn't necessary to test this snippet... just
change bits 15,14,13 @ [prefix_flags] to whatever prior to running any
tests, and the code should act according to what i've described for those
bits....

-----------------------------------------------------------

; enter at find_prefixes with...
; DS:SI = point of disassembly

USE16

find_prefixes:
 mov bx,0FFFFh

next_prefix:
 inc bx

 mov al,[bx+si]
 mov cl,al

 and al,0FCh
 cmp al,064h
 mov al,cl
 jz prefix_386

 and al,0E7h
 cmp al,026h
 mov al,cl
 jz prefix_seg

 and al,0FEh
 cmp al,0F2h
 mov al,cl
 jz prefix_rep

 and al,0FFh
 cmp al,0F0h
 mov al,cl
 jz prefix_lck

 jmp not_prefix

prefix_386:
 and ax,00007h
 cmp ax,00006h
 jb pre_386seg
 sub ax,00005h
 ror ax,00Ah
 or [prefix_flags],ax
 jmp next_prefix
prefix_seg:
 and ax,00018h
 shr ax,003h
pre_386seg:
 mov cx,[prefix_flags]
 and cx,00007h
 cmp cx,00007h
 jz pre_segnoe
 or word [prefix_flags],00008h
 test word [prefix_flags],08000h
 jnz pre_segnoe
 jmp next_prefix
pre_segnoe:
 and word [prefix_flags],0FFF8h
 or word [prefix_flags],ax
 jmp next_prefix
prefix_rep:
 mov cx,[prefix_flags]
 and ax,00001h
 test cx,00020h
 jz pre_repnoe
 or word [prefix_flags],00008h
 test cx,04000h
 jnz pre_rep_1x
 test cx,02000h
 jnz pre_repnoe
 jmp next_prefix
pre_rep_1x:
 mov ax,cx
 ror ax,00Dh
 and ax,00001h
pre_repnoe:
 or ax,00002h
 ror ax,00Ch
 or [prefix_flags],ax
 jmp next_prefix
prefix_lck:
 or word [prefix_flags],01000h
 jmp next_prefix

prefix_flags: dw 08007h

not_prefix: int3

; end at not_prefix with...
;
; all memory except [prefix_flags] is untouched
; [prefix_flags] updated according to prefixes found
;
; DS & SI = unchanged (DS:SI still at point of disassembly)
; BX = number of prefix bytes found
; so [ds:BX+SI] is first non-prefix byte
;
; CX = don't care
; AH = don't care
; AL = value of first non-prefix byte
;
; all other registers untouched

;------------------------------------------
;meaning of word [prefix_flags]
; bit# description
; 15 Segment Override Prefix honored
; 0=first of two is honored
; 1=second of two is honored
; 14,13 Repeat Prefix honored
; 00=first of two is honored
; 01=second of two is honored
; 10=RepN always honored over RepZ
; 11=RepZ always honored over RepN
; 12 Lock Prefix present
; 11,10,09,08 REX prefix bits (not tested for yet)
; 07 Address Size prefix present
; 06 Operand Size prefix present
; 05 Rep prefix present
; 04 Rep prefix type
; 0=RepN (bit0 of prefix byte F2)
; 1=RepZ (bit0 of prefix byte F3)
; 03 Error Flag = Multiple/SameGroup Prefixes
; 02,01,00 Segment Override Prefix
; 111=no segment override
; 110=(reserved for future use)
; 000-101=es/cs/ss/ds/fs/gs,respectively



Relevant Pages

  • disassembler prefix-byte check -- wanting comments good and bad
    ... check the description down at the very bottom of the snippet if things get ... prefix bytes... ... mov cl,al ... jmp next_prefix ...
    (alt.lang.asm)
  • Re: disassembler prefix-byte check -- wanting comments good and bad
    ... > check the description down at the very bottom of the snippet if things get ... mov cl,al ... jz prefix_lck; jz to handler for lock prefix ... jmp next_prefix; otherwise, ...
    (alt.lang.asm)
  • Re: disassembler prefix-byte check -- wanting comments good and bad
    ... > check the description down at the very bottom of the snippet if things get ... mov cl,al ... jz prefix_lck; jz to handler for lock prefix ... jmp next_prefix; otherwise, ...
    (comp.lang.asm.x86)
  • Re: whats the use of "data16 nop" instruction generated by gas on x86 and x86_64
    ... The basic problem is that there aren't different instruction encodings for 16-bit and 32-bit operations; a code segment has a "default" operand size, and if you want the "other" size, you need the 66h prefix. ... For instance, in 16-bit mode a "MOV AX, BX" can be turned into "MOV EAX, EBX" by adding a 66h prefix. ... 90h is the opcode for XCHG AX,AX, so adding one or more 66h prefix bytes change the code from 16 to 32 bit or vice versa. ... BTW, MOVing any register to itself is a two-byte NO-OP, but unlike the 66h/90h combination it isn't specialcased by the decoder, so it does affect the reorder buffer register pressure. ...
    (comp.arch)
  • Re: mov seg, reg/mov reg, seg and size prefix
    ... size prefix byte, for 16-bit only instructions, is all over the map. ... mov ds, ax ... assembler that *was* doing it, at that time. ...
    (comp.lang.asm.x86)