Re: 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 21:09:59 +0000 (UTC)


"Bx.C" <invalid-email-address@invalid.shiragajin> wrote in message
news:%aN8c.61768$zP2.23815@bignews5.bellsouth.net...
> 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....
>

*****************************************************************

HERE's an updated version w/ comments... suggestions and any and all feedback welcome... thanks

-----------------------------------------------------------
USE16

find_prefix:
 mov bx,0FFFFh

next_prefix:
 inc bx ; BX = # of prefix bytes so far

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

 and al,0FCh ; check for 64/65/66/67
 cmp al,064h
 mov al,cl
 jz prefix_386 ; jz to handler for 386 prefixes

 and al,0E7h ; check for 26/2E/36/3E
 cmp al,026h
 mov al,cl
 jz prefix_seg ; jz to handler for seg prefixes

 and al,0FEh ; check for F2/F3
 cmp al,0F2h
 mov al,cl
 jz prefix_rep ; jz to handler for rep prefixes

 cmp al,0F0h ; check for F0
 mov al,cl
 jz prefix_lck ; jz to handler for lock prefix

 jmp not_prefix ; byte @ [bx+si] isn't a prefix byte
   ; last prefix byte has been found

prefix_386:
 and ax,00007h ; 64/65/66/67 = 04/05/06/07
 cmp ax,00006h ; check for 386seg prefixes FS/GS
 jb pre_386seg ; jb if 386 seg prefix
 sub ax,00005h ; 06/07 = 01/02
 ror ax,00Ah ; shift bits to position for prefix_flags
 or [prefix_flags],ax ; set prefix_flag accordingly
 jmp next_prefix ; get next prefix

prefix_seg:
 and ax,00018h ; 26/2E/36/3E = 00/08/10/18
 shr ax,003h ; 00/08/10/18 = 00/01/02/03 (ES/CS/SS/DS)
pre_386seg: ; entering from prefix_386 if 04/05 (FS/GS)
 mov cx,[prefix_flags] ; bring in prefix_flags
 and cx,00007h ; mask for seg-override bits
 cmp cx,00007h ; check for value 7 (no seg-override yet)
 jz pre_segnoe ; jz if ok so we can put one...
 or word [prefix_flags],00008h ; set error flag.. we already have a seg override
 test word [prefix_flags],08000h ; check to see how to handle
 jnz pre_segnoe ; if checkbit was set, use this seg override
 jmp next_prefix ; otherwise, let's just get next prefix
pre_segnoe:
 and word [prefix_flags],0FFF8h ; mask off seg-override
 or word [prefix_flags],ax ; put in new seg-override
 jmp next_prefix ; get next prefix

prefix_rep:
 mov cx,[prefix_flags] ; bring in prefix_flags
 and ax,00001h ; F2/F3 = 00/01
 test cx,00020h ; rep prefix already present?
 jz pre_repnoe ; jz if ok so we can put one...
 or word [prefix_flags],00008h ; set error flag.. we already have a rep prefix
 test cx,04000h ; check to see how to handle...
 jnz pre_rep_1x ; jz if prefix_flags bit14=1
 test cx,02000h ; check whether first or last is honored
 jnz pre_repnoe ; last one honored, let's set it
 jmp next_prefix ; otherwise first honored, let's get next prefix
pre_rep_1x:
 and cx,02001h ; concerned w/ CX bits 13 and 0
 mov ah,al ; copy AL bit 0 to AH
 and ah,cl ; in case CX bit 13 = 0
 or al,cl ; in case CX bit 13 = 1
 test cx,02000h ; check CX bit 13
 jnz pre_rep_1z ; jnz to use AL
 mov al,ah ; else use AH
pre_rep_1z:
 and ax,00001h ; mask off AH
pre_repnoe:
 or ax,00002h ; rep prefix bit at AX bit 0, set bit 1 as well
 ror ax,00Ch ; mov bits 1/0 to position 5/4 for rep prefix flags
 or [prefix_flags],ax ; set rep prefix flags
 jmp next_prefix ; get next prefix

prefix_lck:
 or word [prefix_flags],01000h ; set lock present flag
 jmp next_prefix ; get next prefix

prefix_flags: dw 08007h

not_prefix: int3

;------------------------------------------
;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 ...
    (comp.lang.asm.x86)
  • 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: 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)