home *** CD-ROM | disk | FTP | other *** search
- .386p
- .model small
-
- include dispatch.ase
- include opcodes.asi
- include operands.asi
- PUBLIC TabTo, ReadOverrides, DispatchOperands
- PUBLIC FormatDisassembly, FormatValue, code_address
- PUBLIC PutDword, PutWord,PutByte
- PUBLIC put2,put3,put4
- SZ_QWORD =2
- SZ_TBYTE= 4
-
- .data
- code_address dd 0
- dest2 dd 0
- source2 dd 0
- segs dd 0
- extraoperand OPERAND ?
- source OPERAND ?
- dest OPERAND ?
- nmmnemonic db 10 DUP (?)
- strict db 0
- align
- regs db "alcldlblahchdhbhaxcxdxbxspbpsidi"
- psegs db "escsssdsfsgs"
- crreg db "CR0?23????"
- drreg db "DR0123??67"
- trreg db "TR??????67"
- sudreg db "?R????????"
- scales db " + *2+*4+*8+"
- stalone db "st",0
- st_repz db "repz ",0
- st_repnz db "repnz ",0
-
-
- base0 db "bx+si",0
- base1 db "bx+di",0
- base2 db "bp+si",0
- base3 db "bp+di",0
- base4 db "si",0
- base5 db "di",0
- base6 db "bp",0
- base7 db "bx",0
- st0 db "fword",0 ; Should be DWORD for MATH, FWORD for jmp/call
- st1 db "dword",0
- st2 db "qword",0
- st3 db "word",0
- st4 db "tbyte"
- st5 db 0
- byptr db "byte ptr ",0
- dwptr db "d"
- woptr db "word"
- theptr db " ptr ",0
- stsreg db "ST(",0
- align
- based dd base0,base1,base2,base3,base4,base5,base6,base7
- sts dd st0,st1,st2,st3,st4,st5,st5,st5
-
- .code
-
- strlen PROC
- push edi
- push esi
- push ecx
- push es
- push ds
- pop es
- mov edi,esi
- mov ecx,-1
- sub al,al
- repnz scasb
- mov eax,ecx
- neg eax
- dec eax
- dec eax
- pop es
- pop ecx
- pop esi
- pop edi
- ret
- strlen ENDP
- strcpy PROC
- push es
- push ds
- pop es
- strcpylp:
- lodsb
- stosb
- or al,al
- jnz strcpylp
- pop es
- ret
- strcpy ENDP
- strcat PROC
- mov al,[edi]
- inc edi
- or al,al
- jnz strcat
- dec edi
- jmp strcpy
- strcat ENDP
- CopyExtra PROC
- push esi
- push edi
- mov esi,offset DGROUP:extraoperand
- xchg esi,edi
- push es
- push ds
- pop es
- mov ecx,OPERANDSIZE
- rep movsb
- pop es
- pop edi
- pop esi
- CopyExtra ENDP
- put2 PROC
- mov [esi],ah
- inc esi
- mov [esi],al
- inc esi
- mov BYTE PTR [esi],0
- ret
- put2 ENDP
- put3 PROC
- push eax
- shr eax,8
- mov [esi],ah
- inc esi
- pop eax
- call put2
- ret
- put3 ENDP
- put4 PROC
- push eax
- shr eax,16
- call put2
- pop eax
- call put2
- ret
- put4 ENDP
- SetSeg PROC
- mov [strict],0
- mov [edi + OPERAND.CODE],OM_SEGMENT
- mov [edi + OPERAND.THEREG],al
- ret
- SetSeg ENDP
- SetReg PROC
- mov [strict],0
- mov [edi + OPERAND.CODE],OM_REG
- mov [edi + OPERAND.THEREG],al
- ret
- SetReg ENDP
- ReadRM PROC
- push ecx
- sub ecx,ecx
- mov cl,2
- RM esi
- mov [edi + OPERAND.THEREG],al
- MODX esi
- mov ch,al
- cmp ch,MOD_REG
- jnz short notregreg
- mov [edi + OPERAND.CODE],OM_REG
- mov [strict],0
- sub eax,eax
- pop ecx
- ret
- notregreg:
- bt [edi + OPERAND.OEFLAGS],OMF_ADR32
- jnc adr16
- cmp [edi + OPERAND.THEREG],RM_32_SCALED
- jnz notscaled
- inc cl
- RM esi+1
- mov [edi + OPERAND.THEREG],al
- REG esi+1
- mov [edi + OPERAND.SCALEREG],al
- MODX esi+1
- mov [edi + OPERAND.SCALE],al
- cmp [edi + OPERAND.SCALEREG],RM_32_STACKINDEX
- jz hassp
- bts [edi + OPERAND.OEFLAGS],OMF_SCALED
- hassp:
- cmp [edi + OPERAND.THEREG],RM_32_ABSOLUTE
- jnz basedAndScaled
- cmp ch,MOD_NOOFS
- jnz short basedAndScaled
- mov [edi + OPERAND.CODE],OM_ABSOLUTE
- LONG esi+3
- mov [edi + OPERAND.ADDRESS],eax
- sub eax,eax
- mov al,5
- pop ecx
- ret
- notscaled:
-
- cmp ch,MOD_NOOFS
- jnz basedAndScaled
- cmp [edi + OPERAND.THEREG], RM_32_ABSOLUTE
- jnz basedAndScaled
- mov [edi + OPERAND.CODE], OM_ABSOLUTE
- LONG esi+2
- mov [edi + OPERAND.ADDRESS],eax
- sub eax,eax
- sub eax,eax
- mov al,4
- pop ecx
- ret
- adr16:
- cmp ch,MOD_NOOFS
- jnz basedAndScaled
- cmp [edi + OPERAND.THEREG], RM_16_ABSOLUTE
- jnz basedAndScaled
- mov [edi + OPERAND.CODE], OM_ABSOLUTE
- mov [edi + OPERAND.ADDRESS],eax
- sub eax,eax
- mov al,2
- pop ecx
- ret
- basedAndScaled:
- mov [edi + OPERAND.CODE], OM_BASED
- cmp ch,MOD_ADDR
- jnz short checksigned
- bts [edi + OPERAND.OEFLAGS], OMF_WORD_OFFSET
- push ecx
- sub ch,ch
- mov eax,[esi+ecx]
- pop ecx
- bt [edi + OPERAND.OEFLAGS], OMF_ADR32
- jc dwordx
- and eax,0ffffh
- sub cl,2
- dwordx:
- mov [edi + OPERAND.ADDRESS],eax
- add cl,4
- jmp short readrmdone
- checksigned:
- cmp ch, MOD_SIGNED
- jnz short readrmdone
- bts [edi + OPERAND.OEFLAGS],OMF_SIGNED_OFFSET
- push ecx
- sub ch,ch
- sub eax,eax
- mov al,[esi+ecx]
- pop ecx
- mov [edi + OPERAND.ADDRESS],eax
- inc cl
- readrmdone:
- mov eax,ecx
- sub al,2
- cbw
- cwde
- pop ecx
- ret
- ReadRM ENDP
- RegRM PROC
- mov edi,[dest2]
- REG esi
- call SetReg
- mov edi,[source2]
- call ReadRM
- ret
- RegRM ENDP
- Immediate PROC
- push ecx
- sub ecx,ecx
- mov [edi + OPERAND.CODE],OM_IMMEDIATE
- bt [edi + OPERAND.OEFLAGS],OMF_BYTE
- jnc short inotbyte
- inc cl
- sub eax,eax
- mov al,[esi]
- jmp short i_ret
- inotbyte:
- bt [edi + OPERAND.OEFLAGS], OMF_OP32
- jnc iword
- add cl,4
- LONG esi
- jmp short i_ret
- iword:
- add cl,2
- UINT esi
- i_ret:
- mov [edi + OPERAND.ADDRESS],eax
- mov eax,ecx
- pop ecx
- ret
- Immediate ENDP
- MnemonicChar PROC
- push edi
- mov edi,offset DGROUP:nmmnemonic
- mc2:
- inc edi
- cmp BYTE PTR [edi-1],0
- jnz mc2
- mov [edi-1],al
- mov BYTE PTR [edi],0
- pop edi
- ret
- MnemonicChar ENDP
- ;/* op 1- word reg from bits 0 - 2 of opcode */
- op1 PROC
- btr [edi + OPERAND.OEFLAGS],OMF_BYTE
- mov al,[esi]
- B02
- call SetReg
- sub eax,eax
- ret
- op1 ENDP
- ;/* Op2 acc, reg bits 0-2 of opcode */
- op2 PROC
- btr [edi + OPERAND.OEFLAGS],OMF_BYTE
- btr [ebx + OPERAND.OEFLAGS],OMF_BYTE
- mov al,REG_EAX
- call SetReg
- mov edi,ebx
- mov al,[esi]
- and al,7
- call SetReg
- sub eax,eax
- ret
- op2 ENDP
- ;/* op3 - seg from b3-5 of opcode */
- op3 PROC
- mov al,[esi]
- B35
- call SetSeg
- sub eax,eax
- ret
- op3 ENDP
- ;/* op4 - REGRM with b1 of opcode set reg is dest else source */
- op4 PROC
- bt DWORD PTR [esi],1
- jc short op4nox
- xchg ebx,edi
- op4nox:
- mov [dest2],edi
- mov [source2],ebx
- call RegRM
- ret
- op4 ENDP
- ;/* op5 - use RM only */
- op5 PROC
- call ReadRM
- ret
- op5 ENDP
- ;/* op6 READRM for shift */
- op6 PROC
- call ReadRM
- sub ecx,ecx
- mov cl,al
- mov edi,ebx
- mov [edi + OPERAND.CODE],OM_SHIFT
- bt DWORD PTR [esi],4
- jnc short op6cnt
- bt DWORD PTR [esi],1
- jnc op61
- bts [edi + OPERAND.OEFLAGS],OMF_CL
- jmp short op6done
- op61:
- mov [edi + OPERAND.ADDRESS],1
- jmp short op6done
- op6cnt:
- sub eax,eax
- movzx eax,BYTE PTR [esi+ecx+2]
- inc cl
- mov [edi + OPERAND.ADDRESS],eax
- op6done:
- mov eax,ecx
- ret
- op6 ENDP
- ;/* op 7 regrm with reg dest */
- op7 PROC
- mov [dest2],edi
- mov [source2],ebx
- call RegRM
- ret
- op7 ENDP
- ;/* OP8 - word regrm with reg dest */
- op8 PROC
- btr [edi + OPERAND.OEFLAGS],OMF_BYTE
- btr [ebx + OPERAND.OEFLAGS],OMF_BYTE
- jmp op7
- op8 ENDP
- ;/* op 9 - interrupts */
- op9 PROC
- mov [strict],0
- sub eax,eax
- mov al,3
- bt DWORD PTR [esi],0
- jnc short op9int3
- mov al,[esi+1]
- op9int3:
- mov [edi + OPERAND.ADDRESS],eax
- mov BYTE PTR [edi + OPERAND.CODE],OM_INT
- sub al,al
- ret
- op9 ENDP
- ;/* op 10, short relative branch */
- op10 PROC
- mov [strict],0
- mov [edi + OPERAND.CODE],OM_SHORTBRANCH
- movsx eax,BYTE PTR [esi+1]
- inc eax
- inc eax
- add eax,[code_address]
- mov [edi + OPERAND.ADDRESS],eax
- bt [edi + OPERAND.OEFLAGS],OMF_OP32
- jc short op10notword
- and [edi + OPERAND.ADDRESS],0ffffh
- op10notword:
- sub eax,eax
- ret
- op10 ENDP
- ;/* op 11 RM, immediate */
- op11 PROC
- call ReadRM
- movzx ecx,al
- mov edi,ebx
- push esi
- add esi,ecx
- add esi,2
- call Immediate
- add cl,al
- pop esi
- mov eax,ecx
- ret
- op11 ENDP
- ;/* op 12 - acc, immediate */
- op12 PROC
- mov al,REG_EAX
- call SetReg
- mov edi,ebx
- inc esi
- call Immediate
- dec esi
- ret
- op12 ENDP
- ;/* op 13 absolute, acc*/
- op13 PROC
- sub ecx,ecx
- mov [edi + OPERAND.CODE],OM_ABSOLUTE
- bt [edi + OPERAND.OEFLAGS],OMF_ADR32
- jnc short op13word
- LONG esi+1
- inc cl
- inc cl
- jmp short op13fin
- op13word:
- UINT esi+1
- op13fin:
- mov [edi + OPERAND.ADDRESS],eax
- mov edi,ebx
- mov al,REG_EAX
- call SetReg
- mov eax,ecx
- ret
- op13 ENDP
- ;/* op 14 - RM, immediate, b01 of opcode != 1 for byte */
- op14 PROC
- call ReadRM
- movzx ecx,al
- mov al,[esi]
- B01
- jnz short op14checkbyte
- bts [ebx + OPERAND.OEFLAGS],OMF_BYTE
- bts [edi + OPERAND.OEFLAGS],OMF_BYTE
- jmp short op14source
- op14checkbyte:
- btr [ebx + OPERAND.OEFLAGS],OMF_BYTE
- cmp al,1
- jz short op14check2
- bts [ebx + OPERAND.OEFLAGS],OMF_BYTE
- op14check2:
- btr [edi + OPERAND.OEFLAGS],OMF_BYTE
- op14source:
- mov edi,ebx
- push esi
- add esi,ecx
- add esi,2
- call Immediate
- pop esi
- add cl,al
- mov al,[esi]
- B01
- cmp al,3
- jnz op14done
- bt [edi + OPERAND.OEFLAGS],OMF_BYTE
- jnc op14done
- bts [edi + OPERAND.OEFLAGS],OMF_SIGNED
- mov eax,[edi + OPERAND.ADDRESS]
- cbw
- cwde
- mov [edi + OPERAND.ADDRESS],eax
- op14done:
- mov eax,ecx
- ret
- op14 ENDP
- ;/* op 15 - acc, immediate, B3 of opcode clear for byte */
- op15 PROC
- mov al,[esi]
- B02
- call SetReg
- bt DWORD PTR [esi],3
- jnc op15byte
- btr [edi + OPERAND.OEFLAGS],OMF_BYTE
- btr [ebx + OPERAND.OEFLAGS],OMF_BYTE
- jmp short op15source
- op15byte:
- bts [edi + OPERAND.OEFLAGS],OMF_BYTE
- bts [ebx + OPERAND.OEFLAGS],OMF_BYTE
- op15source:
- mov edi,ebx
- inc esi
- call Immediate
- dec esi
- ret
- op15 ENDP
- ;/* op 16 - seg,readrm, if B1 of opcode seg is dest else source */
- op16 PROC
- bt DWORD PTR [esi],1
- jc noswap
- xchg ebx,edi
- noswap:
- REG esi
- call SetSeg
- mov edi,ebx
- btr [edi + OPERAND.OEFLAGS],OMF_BYTE
- call ReadRM
- ret
- op16 ENDP
- ;/* op 17, far return */
- op17 PROC
- mov [strict],0
- mov [edi + OPERAND.CODE],OM_RETURN
- btr [edi + OPERAND.OEFLAGS],OMF_ADR32
- btr [edi + OPERAND.OEFLAGS],OMF_OP32
- btr [edi + OPERAND.OEFLAGS],OMF_BYTE
- UINT esi+1
- mov [edi + OPERAND.ADDRESS],eax
- sub eax,eax
- ret
- op17 ENDP
- ;/* op 18, far branch/call */
- op18 PROC
- sub ecx,ecx
- mov [strict],0
- mov [edi + OPERAND.CODE],OM_FARBRANCH
- btr [edi + OPERAND.OEFLAGS],OMF_BYTE
- bt [edi + OPERAND.OEFLAGS],OMF_OP32
- jnc short op18word
- inc cl
- inc cl
- LONG esi+1
- jmp short op18fin
- op18word:
- UINT esi+1
- op18fin:
- mov [edi + OPERAND.ADDRESS],eax
- UINT esi+ecx+3
- mov [edi + OPERAND.OESEG],ax
- mov eax,ecx
- ret
- op18 ENDP
- ;/* op 19 - ESC, mnem of bits 0-2 of opcode, imm,readrm */
- op19 PROC
- mov [edi + OPERAND.CODE],OM_IMMEDIATE
- bts [edi + OPERAND.OEFLAGS],OMF_BYTE
- mov al,[esi]
- and al,7
- shl al,3
- mov ah,[esi+1]
- shr ah,3
- and ah,7
- or al,ah
- sub ah,ah
- cwde
- mov [edi+ OPERAND.ADDRESS],eax
- mov edi,ebx
- call ReadRM
- ret
- op19 ENDP
- ;/* op 20 - long branch */
- op20 PROC
- mov [strict],0
- sub ecx,ecx
- mov [edi + OPERAND.CODE],OM_LONGBRANCH
- bt [edi + OPERAND.OEFLAGS],OMF_OP32
- jnc short op20word
- LONG esi+1
- inc cl
- inc cl
- jmp short op20fin
- op20word:
- UINT esi+1
- op20fin:
- add eax,[code_address]
- test [segs],SG_TWOBYTEOP
- jz op20xx
- inc eax
- op20xx:
- add eax,ecx
- add eax,3
- bt [edi + OPERAND.OEFLAGS],OMF_OP32
- jc op20done
- and eax,0ffffh
- op20done:
- mov [edi + OPERAND.ADDRESS],eax
- mov eax,ecx
- ret
- op20 ENDP
- ;/* op21 acc,dx */
- op21 PROC
- mov al,REG_EAX
- call SetReg
- mov edi,ebx
- btr [edi + OPERAND.OEFLAGS],OMF_OP32
- btr [edi + OPERAND.OEFLAGS],OMF_BYTE
- mov al,REG_DX
- call SetReg
- sub eax,eax
- ret
- op21 ENDP
- ;/* op22 - dx,acc */
- op22 PROC
- btr [edi + OPERAND.OEFLAGS],OMF_OP32
- btr [edi + OPERAND.OEFLAGS],OMF_BYTE
- mov al,REG_DX
- call SetReg
- mov edi,ebx
- mov al,REG_EAX
- call SetReg
- sub eax,eax
- ret
- op22 ENDP
- ;/* op23 - port,acc where B1 of opcode set is port dest */
- op23 PROC
- bt DWORD PTR [esi],1
- jc short op20noswap
- xchg ebx,edi
- op20noswap:
- bts [edi + OPERAND.OEFLAGS],OMF_BYTE
- mov [edi + OPERAND.CODE],OM_PORT
- movzx eax,BYTE PTR [esi+1]
- mov [edi + OPERAND.ADDRESS],eax
- mov edi,ebx
- mov al,REG_EAX
- call SetReg
- sub eax,eax
- ret
- op23 ENDP
- ;/* op 24 acc, absolute */
- op24 PROC
- sub ecx,ecx
- mov al,REG_EAX
- call SetReg
- mov edi,ebx
- mov [edi + OPERAND.CODE],OM_ABSOLUTE
- bt [edi + OPERAND.OEFLAGS],OMF_ADR32
- jnc short op24word
- inc cl
- inc cl
- LONG esi+1
- jmp short op24done
- op24word:
- UINT esi+1
- op24done:
- mov [edi + OPERAND.ADDRESS],eax
- mov eax,ecx
- ret
- op24 ENDP
- ;/* op 25 - immediate byte or word */
- op25 PROC
- mov [strict],0
- bts [edi + OPERAND.OEFLAGS],OMF_BYTE
- bt DWORD PTR [esi],1
- jc short op25fin
- btr [edi + OPERAND.OEFLAGS],OMF_BYTE
- op25fin:
- push esi
- inc esi
- call Immediate
- pop esi
- ret
- op25 ENDP
- ;/* op 26, immediate 2byte,byte */
- op26 PROC
- mov [strict],0
- btr [edi + OPERAND.OEFLAGS],OMF_BYTE
- btr [edi + OPERAND.OEFLAGS],OMF_OP32
- push esi
- inc esi
- call Immediate
- mov edi,ebx
- bts [edi + OPERAND.OEFLAGS],OMF_BYTE
- btr [edi + OPERAND.OEFLAGS],OMF_OP32
- inc esi
- inc esi
- call Immediate
- pop esi
- sub eax,eax
- ret
- op26 ENDP
- ;/* op 27 - string */
- op27 PROC
- mov al,'d'
- bt [edi + OPERAND.OEFLAGS],OMF_OP32
- jc short op27pc
- mov al,'w'
- op27pc:
- call MnemonicChar
- sub eax,eax
- ret
- op27 ENDP
- ;/* op 28 - source = REG, dest = RM */
- op28 PROC
- REG esi
- call SetReg
- mov edi,ebx
- RM esi
- call SetReg
- sub eax,eax
- ret
- op28 ENDP
- ;/* op 29 - dest = RM, immediate */
- op29 PROC
- bts [edi + OPERAND.OEFLAGS],OMF_BYTE
- RM esi
- call SetReg
- mov edi,ebx
- bts [edi + OPERAND.OEFLAGS],OMF_BYTE
- push esi
- inc esi
- inc esi
- call Immediate
- pop esi
- sub eax,eax
- ret
- op29 ENDP
- ;/* op30 - RM, shift with B3 of stream selecting COUNT or CL*/
- op30 PROC
- call ReadRM
- mov ecx,eax
- mov edi,ebx
- mov [edi + OPERAND.CODE],OM_SHIFT
- bt DWORD PTR [esi],3
- jnc op30cl
- mov eax,[esi+ecx+2]
- inc ecx
- jmp short op30done
- op30cl:
- bts [edi + OPERAND.OEFLAGS],OMF_CL
- op30done:
- mov eax,ecx
- ret
- op30 ENDP
- ;/* op 31- reg, rm, count where B1 of opcode = byte/word */
- op31 PROC
- call CopyExtra
- REG esi
- call SetReg
- mov edi,ebx
- call ReadRM
- mov ecx,eax
- mov edi,offset DGROUP:extraoperand
- bts [edi + OPERAND.OEFLAGS],OMF_BYTE
- bt DWORD PTR [esi],1
- jc short op31byte
- btr [edi + OPERAND.OEFLAGS],OMF_BYTE
- op31byte:
- push esi
- inc esi
- inc esi
- call Immediate
- pop esi
- add eax,ecx
- ret
- op31 ENDP
- ;/* op32 - 386 special regs */
- op32 PROC
- movzx ecx,WORD PTR [esi]
- and cx,0c005h
- cmp cx,0c000h
- mov al,OM_CRX
- jz short op32gotype
- cmp cx,0c001h
- mov al,OM_DRX
- jz short op32gotype
- cmp cx,0c004h
- mov al,OM_TRX
- jz short op32gotype
- mov al,OM_SUD
- op32gotype:
- btr [edi + OPERAND.OEFLAGS],OMF_BYTE
- btr [ebx + OPERAND.OEFLAGS],OMF_BYTE
- bts [edi + OPERAND.OEFLAGS],OMF_OP32
- bts [ebx + OPERAND.OEFLAGS],OMF_OP32
- bt DWORD PTR [esi],1
- jc op32noswap
- xchg ebx,edi
- op32noswap:
- mov [edi + OPERAND.CODE],al
- REG esi
- mov [edi + OPERAND.THEREG],al
- mov edi,ebx
- RM esi
- call SetReg
- sub eax,eax
- ret
- op32 ENDP
- ;/* op33 - reg,rm,shiftcnt where B3 = reg source, b0 = shift cl */
- op33 PROC
- btr [edi + OPERAND.OEFLAGS],OMF_BYTE
- btr [ebx + OPERAND.OEFLAGS],OMF_BYTE
- call CopyExtra
- call ReadRM
- mov ecx,eax
- REG esi
- mov edi,ebx
- call SetReg
- mov edi,offset DGROUP:extraoperand
- mov [edi + OPERAND.CODE],OM_SHIFT
- bt DWORD PTR [esi],0
- jnc short getofs
- bts [edi + OPERAND.OEFLAGS],OMF_CL
- jmp short op33done
- getofs:
- movzx eax,BYTE PTR [esi+ecx+2]
- op33done:
- mov eax,ecx
- ret
- op33 ENDP
- ;/* op 34 - push & pop word */
- op34 PROC
- test [segs],SG_TWOBYTEOP
- jnz short op34twobyte
- test [segs],SG_OPSIZ
- jnz short op34fin
- mov [strict],0
- op34fin:
- call ReadRM
- ret
- op34twobyte:
- btr [edi+OPERAND.OEFLAGS],OMF_OP32
- btr [edi + OPERAND.OEFLAGS],OMF_OP32
- jmp op34fin
- op34 ENDP
- ;/* op 35 -floating RM */
- op35 PROC
- mov [strict],0
- mov ax,[esi]
- and ax,0d0deh
- cmp ax,0d0deh
- jnz short op35nop
- mov al,'p'
- call MnemonicChar
- op35nop:
- MODX esi
- cmp al,3
- jnz short op35fsttab
- bts [edi + OPERAND.OEFLAGS],OMF_FST
- jmp short op35fin
- op35fsttab:
- bts [edi + OPERAND.OEFLAGS],OMF_FSTTAB
- movzx eax,BYTE PTR [edi]
- B12
- shl eax, OM_FTAB
- or [edi + OPERAND.OEFLAGS],ax
- op35fin:
- call ReadRM
- ret
- op35 ENDP
- ;/* op 36 - sized floating RM */
- op36 PROC
- mov cx,SZ_QWORD
- mov [strict],0
- mov ax,[esi]
- and ax,2807h
- cmp ax,2807h
- jz short op36notbyte
- mov cx,SZ_TBYTE
- op36notbyte:
- bts [edi + OPERAND.OEFLAGS],OMF_FSTTAB
- shl ecx,OM_FTAB
- or [edi + OPERAND.OEFLAGS],cx
- call ReadRM
- ret
- op36 ENDP
- ;/* OP 37 - floating MATH */
- op37 PROC
- sub edx,edx
- mov [strict],0
- mov ax,[esi]
- and ax,0c0deh
- cmp ax,0c0deh
- jnz short op37noflop
- inc edx
- op37noflop:
- REG esi
- and al,5
- xor al,dl
- cmp al,5
- jnz short op37nor
- mov al,'r'
- call MnemonicChar
- op37nor:
- MODX esi
- cmp al,3
- jz op37reg
- bts [edi + OPERAND.OEFLAGS],OMF_FSTTAB
- mov al,[esi]
- B12
- shl eax,OM_FTAB
- or [edi + OPERAND.OEFLAGS],ax
- call ReadRM
- jmp short op37done
- op37reg:
- test BYTE PTR [esi],6
- jz short op37nop
- mov al,'p'
- call MnemonicChar
- op37nop:
- bt DWORD PTR [esi],2
- jc short op37noswap
- xchg ebx,edi
- op37noswap:
- RM esi
- call SetReg
- bts [edi + OPERAND.OEFLAGS],OMF_FST
- mov edi,ebx
- mov [edi + OPERAND.CODE],OM_FSTREG
- sub eax,eax
- op37done:
- ret
- op37 ENDP
- op38 PROC
- mov [strict],0
- bts [edi + OPERAND.OEFLAGS],OMF_FSTTAB
- call ReadRM
- ret
- op38 ENDP
- ;/* OP39 - word regrm with reg source */
- op39 PROC
- btr [edi + OPERAND.OEFLAGS],OMF_BYTE
- btr [ebx + OPERAND.OEFLAGS],OMF_BYTE
- call op40
- ret
- op39 ENDP
- ;/* op 40 regrm with reg source */
- op40 PROC
- mov [dest2],ebx
- mov [source2],edi
- call RegRM
- ret
- op40 ENDP
- ;/* op 41 reg, bitnum */
- op41 PROC
- btr [edi+OPERAND.OEFLAGS],OMF_BYTE
- call ReadRM
- mov ecx,eax
- mov edi,ebx
- bts [edi+OPERAND.OEFLAGS],OMF_BYTE
- push esi
- add esi,ecx
- add esi,2
- call Immediate
- pop esi
- mov eax,ecx
- ret
- op41 ENDP
- ;/* op 42 mixed regrm with reg dest & strictness enforced */
- op42 PROC
- mov [dest2],edi
- mov [source2],ebx
- btr [edi + OPERAND.OEFLAGS],OMF_BYTE
- btr [ebx + OPERAND.OEFLAGS],OMF_OP32
- call RegRM
- mov [strict],1
- ret
- op42 ENDP
- ;/* op 43 CWDE
- op43 PROC
- bt [edi + OPERAND.OEFLAGS],OMF_OP32
- jnc short op43nochng
- push esi
- mov esi,offset DGROUP:nmmnemonic + 1
- mov eax,"wde"
- call put3
- mov BYTE PTR [esi],0
- pop esi
- sub eax,eax
- op43nochng:
- ret
- op43 ENDP
- ReadOverrides PROC
-
- ro_lp:
- sub eax,eax
- lods BYTE PTR [esi]
- cmp al,64h
- jc short testseg
- cmp al,68h
- jnc short testseg
- sub al,64h
- mov ebx,SG_FS
- ro_found:
- mov cl,al
- shl ebx,cl
- or [segs],ebx
- jmp short ro_lp
- testseg:
- push eax
- and al,0e7h
- cmp al,026h
- pop eax
- jnz testrep
- mov ebx,1
- shr eax,3
- and al,3
- jmp ro_found
- testrep:
- sub al,0f2h
- cmp al,2
- jnc ro_done
- mov ebx,SG_REPNZ
- jmp short ro_found
- ro_done:
- dec esi
- ret
- ReadOverrides ENDP
- DispatchOperands PROC
- push ebx
- mov edi,offset DGROUP:nmmnemonic
- push esi
- mov esi,[ebx + OPCODE.MNEMONIC]
- call strcpy
- pop esi
- mov [strict],TRUE
- movzx eax,[ebx + OPCODE.OPERANDS]
- push eax
- mov edi,offset DGROUP:dest
- mov ebx,offset DGROUP:source
- cmp BYTE PTR [esi-1],0fh
- jnz short notwobyte
- or [segs],SG_TWOBYTEOP
- notwobyte:
- mov eax,offset DGROUP:extraoperand
- mov [eax + OPERAND.CODE],0
- mov [edi + OPERAND.CODE],0
- mov [ebx + OPERAND.CODE],0
- mov [edi + OPERAND.OEFLAGS],0
- mov [ebx + OPERAND.OEFLAGS],0
-
- bt DWORD PTR [esi],0
- jc notbyte
- bts [edi + OPERAND.OEFLAGS],OMF_BYTE
- bts [ebx + OPERAND.OEFLAGS],OMF_BYTE
- notbyte:
- test [segs],SG_ADRSIZ
- jnz do_word1
- bts [edi + OPERAND.OEFLAGS],OMF_ADR32
- bts [ebx + OPERAND.OEFLAGS],OMF_ADR32
- do_word1:
- test [segs],SG_OPSIZ
- jnz do_word2
- bts [edi + OPERAND.OEFLAGS],OMF_OP32
- bts [ebx + OPERAND.OEFLAGS],OMF_OP32
- do_word2:
-
- pop eax
- or eax,eax
- jz nodispatch
- dec al
- push 0
- call TableDispatch
- dd 42
- dd op1, op2, op3, op4, op5, op6, op7, op8, op9, op10
- dd op11, op12, op13, op14, op15, op16, op17, op18, op19, op20
- dd op21, op22, op23, op24, op25, op26, op27, op28, op29, op30
- dd op31, op32, op33, op34, op35, op36, op37, op38, op39, op40
- dd op41, op42, op43
- add esi,eax
- nodispatch:
- pop ebx
- movzx eax,[ebx + OPCODE.OCLENGTH]
- add esi,eax
- ret
- DispatchOperands ENDP
- DoStrict PROC
- push edi
- push esi
- test [strict],-1
- jz short floatstrict
- bt [edi + OPERAND.OEFLAGS],OMF_BYTE
- jnc chkdwptr
- mov edi,esi
- mov esi,offset DGROUP:byptr
- jmp short strictend
- chkdwptr:
- bt [edi + OPERAND.OEFLAGS],OMF_OP32
- mov edi,esi
- jnc mkwordptr
- mov esi,offset DGROUP:dwptr
- jmp short strictend
- mkwordptr:
- mov esi,offset DGROUP:woptr
- jmp short strictend
- floatstrict:
- bt [edi + OPERAND.OEFLAGS],OMF_FSTTAB
- jnc strictdone
- movzx eax,[edi + OPERAND.OEFLAGS]
- shr eax,OM_FTAB
- and eax,7
- mov edi,esi
- push edi
- mov esi,offset DGROUP:sts
- mov esi,[esi + eax * 4]
- call strcat
- mov esi,offset DGROUP:theptr
- pop edi
- strictend:
- call strcat
- strictdone:
- pop esi
- call strlen
- add esi,eax
- pop edi
- ret
- DoStrict ENDP
- TabTo PROC
- cbw
- cwde
- mov ecx,eax
- call strlen
- xchg eax,ecx
- sub eax,ecx
- jnc tt_noover
- add eax,ecx
- add esi,eax
- jmp short tt_done
- tt_noover:
- add esi,ecx
- mov ecx,eax
- tabtlp:
- mov BYTE PTR [esi],' '
- inc esi
- loop tabtlp
- tt_done:
- mov BYTE PTR [esi],0
- ret
- TabTo ENDP
- GetST PROC
- mov al,[edi + OPERAND.THEREG]
- xchg esi,edi
- mov esi,offset DGROUP:stsreg
- call strcpy
- xchg esi,edi
- dec esi
- mov BYTE PTR [esi],')'
- inc esi
- mov BYTE PTR [esi],0
- ret
- GetST ENDP
- GetStdReg PROC
- push edi
- or al,al
- jnz short gsrnoe
- mov BYTE PTR [esi],'e'
- inc esi
- gsrnoe:
- mov edi,offset DGROUP:regs
- mov ax,[edi + ecx *2]
- mov [esi],al
- inc esi
- mov [esi],ah
- inc esi
- mov BYTE PTR [esi],0
- pop edi
- ret
- GetStdReg ENDP
- GetReg PROC
- movzx ecx,al
- sub al,al
- inc al
- bt [edi + OPERAND.OEFLAGS],OMF_BYTE
- jc short grno32
- bt [edi + OPERAND.OEFLAGS],OMF_OP32
- jnc short grno32
- dec al
- grno32:
- bt [edi + OPERAND.OEFLAGS],OMF_BYTE
- jc short isbyte
- or cl,8
- isbyte:
- call GetStdReg
- ret
- GetReg ENDP
- GetSpecial PROC
- mov al,[ebx]
- mov [esi],al
- inc esi
- inc ebx
- mov al,[ebx]
- mov [esi],al
- inc esi
- inc ebx
- movzx eax,[edi + OPERAND.THEREG]
- mov al,[ebx +eax]
- mov [esi],al
- inc esi
- mov BYTE PTR [esi],0
- ret
- GetSpecial ENDP
- GetSeg PROC
- push edi
- push eax
- mov edi,offset DGROUP:psegs
- mov ax,[edi + ecx *2]
- mov [esi],al
- inc esi
- mov [esi],ah
- inc esi
- pop eax
- or al,al
- mov al,':'
- jz short nocolon
- mov [esi],al
- inc esi
- nocolon:
- mov BYTE PTR [esi],0
- pop edi
- ret
- GetSeg ENDP
- SegOverride PROC
- mov al,1
- sub ecx,ecx
- test [segs],SG_ES
- jz short so_testcs
- call GetSeg
- so_testcs:
- inc ecx
- test [segs],SG_CS
- jz short so_testss
- call GetSeg
- so_testss:
- inc ecx
- test [segs],SG_SS
- jz short so_testds
- call GetSeg
- so_testds:
- inc ecx
- test [segs],SG_DS
- jz short so_testfs
- call GetSeg
- so_testfs:
- inc ecx
- test [segs],SG_FS
- jz short so_testgs
- call GetSeg
- so_testgs:
- inc ecx
- test [segs],SG_GS
- jz short so_done
- call GetSeg
- so_done:
- mov [segs],0
- ret
- SegOverride ENDP
- Scaled PROC
- push DWORD PTR [edi + OPERAND.OEFLAGS]
- btr [edi + OPERAND.OEFLAGS],OMF_BYTE
- bts [edi + OPERAND.OEFLAGS],OMF_OP32
- or al,al
- jz short notbased
- sub al,al
- mov al,[edi + OPERAND.THEREG]
- call GetReg
- notbased:
- bt [edi + OPERAND.OEFLAGS],OMF_SCALED
- jnc short notscaled2
- movzx ecx,[edi + OPERAND.SCALE]
- mov eax,ecx
- add ecx,ecx
- add ecx,eax
- add ecx,offset DGROUP:scales
- mov eax,[ecx]
- call put3
- or al,1
- mov al,[edi + OPERAND.SCALEREG]
- call GetReg
- notscaled2:
- pop DWORD PTR [edi + OPERAND.OEFLAGS]
- ret
- Scaled ENDP
- FOM_FSTREG PROC
- mov edi,offset DGROUP:stalone
- call strcat
- ret
- FOM_FSTREG ENDP
- FOM_CRX PROC
- mov ebx,offset DGROUP:crreg
- call GetSpecial
- ret
- FOM_CRX ENDP
- FOM_DRX PROC
- mov ebx,offset DGROUP:drreg
- call GetSpecial
- ret
- FOM_DRX ENDP
- FOM_TRX PROC
- mov ebx,offset DGROUP:trreg
- call GetSpecial
- ret
- FOM_TRX ENDP
- FOM_SUD PROC
- mov ebx,offset DGROUP:sudreg
- call GetSpecial
- ret
- FOM_SUD ENDP
- FOM_PORT PROC
- mov al,SY_PORT
- format:
- call FormatValue
- ret
- FOM_PORT ENDP
- FOM_INT PROC
- mov al,SY_INTR
- jmp short format
- FOM_INT ENDP
- FOM_SHIFT PROC
- bt [edi + OPERAND.OEFLAGS],OMF_CL
- jnc fos_notcl
- mov ax,"cl"
- call put2
- ret
- fos_notcl:
- cmp [edi + OPERAND.ADDRESS],1
- mov al,SY_SHIFT
- jnz format
- mov BYTE PTR [esi],'1'
- inc esi
- mov BYTE PTR [esi],0
- ret
- FOM_SHIFT ENDP
- FOM_RETURN PROC
- mov al,SY_RETURN
- jmp format
- FOM_RETURN ENDP
- FOM_SHORTBRANCH PROC
- mov al,SY_SHORTBRANCH
- jmp format
- FOM_SHORTBRANCH ENDP
- FOM_LONGBRANCH PROC
- mov al,SY_LONGBRANCH
- jmp format
- FOM_LONGBRANCH ENDP
- FOM_FARBRANCH PROC
- mov al,SY_SEGMENT
- call format
- mov BYTE PTR [esi],':'
- inc esi
- mov al,SY_ABSBRANCH
- call format
- ret
- FOM_FARBRANCH ENDP
- FOM_ABSOLUTE PROC
- call DoStrict
- call SegOverride
- mov BYTE PTR [esi],'['
- inc esi
- mov BYTE PTR [esi],0
- bt [edi + OPERAND.OEFLAGS],OMF_SCALED
- jnc foa_notscaled
- mov al,SY_WORDOFS
- call FormatValue
- sub eax,eax
- call Scaled
- jmp short foa_finish
- foa_notscaled:
- mov al,SY_ABSOLUTE
- call FormatValue
- foa_finish:
- mov BYTE PTR [esi],']'
- inc esi
- mov BYTE PTR [esi],0
- ret
- FOM_ABSOLUTE ENDP
- FOM_IMMEDIATE PROC
- bt [edi + OPERAND.OEFLAGS],OMF_BYTE
- mov al,SY_WORDIMM
- jnc short absformat
- mov al,SY_SIGNEDIMM
- bt [edi + OPERAND.OEFLAGS],SY_SIGNEDIMM
- jc short absformat
- mov al,SY_SIGNEDIMM
- absformat:
- jmp format
- FOM_IMMEDIATE ENDP
- FOM_REG PROC
- bt [edi + OPERAND.OEFLAGS],OMF_FST
- jnc short foreg
- call GetST
- ret
- foreg:
- mov al,[edi + OPERAND.THEREG]
- call GetReg
- ret
- FOM_REG ENDP
- FOM_BASED PROC
- call DoStrict
- call SegOverride
- mov BYTE PTR [esi],'['
- inc esi
- mov BYTE PTR [esi],0
- bt [edi + OPERAND.OEFLAGS],OMF_ADR32
- jnc fob_notscaled
- mov al,1
- call Scaled
- jmp short fob2
- fob_notscaled:
- push edi
- push esi
- movzx eax,BYTE PTR [edi + OPERAND.THEREG]
- xchg esi,edi
- mov esi,offset DGROUP:based
- mov esi,[esi + eax * 4]
- call strcpy
- pop esi
- pop edi
- call strlen
- add esi,eax
- fob2:
- test [edi + OPERAND.OEFLAGS],OMF_OFFSET
- jz short fob_noofs
- bt [edi + OPERAND.OEFLAGS],OMF_SIGNED_OFFSET
- mov al,SY_SIGNEDOFS
- jc fob_format
- mov al,SY_WORDOFS
- bt [edi + OPERAND.OEFLAGS],OMF_WORD_OFFSET
- jc fob_format
- mov al,SY_BYTEOFS
- fob_format:
- call FormatValue
- fob_noofs:
- mov BYTE PTR [esi],']'
- inc esi
- mov BYTE PTR [esi],0
- ret
- FOM_BASED ENDP
- FOM_SEGMENT PROC
- movzx ecx,[edi + OPERAND.THEREG]
- sub eax,eax
- call GetSeg
- ret
- FOM_SEGMENT ENDP
- PutOperand PROC
- call strlen
- add esi,eax
- mov al,[edi + OPERAND.CODE]
- dec al
- js short po_none
- push 0
- call TableDispatch
- dd 17
- DD FOM_BASED
- DD FOM_SEGMENT
- DD FOM_REG
- DD FOM_IMMEDIATE
- DD FOM_ABSOLUTE
- DD FOM_FARBRANCH
- DD FOM_LONGBRANCH
- DD FOM_SHORTBRANCH
- DD FOM_RETURN
- DD FOM_SHIFT
- DD FOM_INT
- DD FOM_PORT
- DD FOM_SUD
- DD 0
- DD FOM_TRX
- DD FOM_DRX
- DD FOM_CRX
- DD FOM_FSTREG
- po_none:
- ret
- PutOperand ENDP
- FormatDisassembly PROC
- ENTER 256,0
- push esi
- lea edi,[ebp-256]
- mov BYTE PTR [edi],0
- test [segs],SG_REPZ
- push edi
- jz fd_notrepz
- mov esi,offset DGROUP:st_repz
- call strcpy
- fd_notrepz:
- test [segs],SG_REPNZ
- jz fd_notrepnz
- mov esi,offset DGROUP:st_repnz
- call strcpy
- fd_notrepnz:
- pop edi
- xchg esi,edi
- call strlen
- add esi,eax
- xchg esi,edi
- mov esi,offset DGROUP:nmmnemonic
- call strcat
- lea esi,[ebp-256]
- sub eax,eax
- mov al,TAB_ARGPOS
- call TabTo
- mov edi,offset DGROUP:dest
- call PutOperand
- mov edi,offset DGROUP:source
- test [edi + OPERAND.CODE],-1
- jz short nosource
- mov BYTE PTR [esi],','
- inc esi
- mov BYTE PTR [esi],0
- call PutOperand
- nosource:
- mov edi,offset DGROUP:extraoperand
- test [edi + OPERAND.CODE],-1
- jz short noextra
- mov BYTE PTR [esi],','
- inc esi
- mov BYTE PTR [esi],0
- call PutOperand
- noextra:
- pop esi
- mov BYTE PTR [esi],0
- call SegOverride
- mov edi,esi
- lea esi,[ebp-256]
- call strcat
- LEAVE
- ret
- FormatDisassembly ENDP
- PutDword:
- push eax ; To print a dword
- shr eax,16 ; Print the high 16 bits
- call PutWord
- pop eax ; And the low 16 bits
- PutWord:
- push eax ; To print a word
- mov al,ah ; Print the high byte
- call PutByte
- pop eax ; And the low byte
- PutByte:
- push eax ; To print a byte
- shr eax,4 ; Print the high nibble
- call putnibble
- pop eax ; And the low nibble
- putnibble:
- and al,0fh ; Get a nibble
- add al,'0' ; Make it numeric
- cmp al,'9' ; If supposed to be alphabetic
- jle onib
- add al,7 ; Add 7
- onib:
- mov [esi],al
- inc esi
- ret
- ABSX PROC
- bt eax,31
- jnc noabs
- neg eax
- noabs:
- ret
- ABSX ENDP
- FSY_SIGNEDOFS PROC
- bt [edi + OPERAND.ADDRESS],31
- mov eax,"+os_"
- jnc fso_pos
- mov eax,"-os_"
- fso_pos:
- call put4
- mov eax,[edi + OPERAND.ADDRESS]
- call ABSX
- call PutByte
- mov BYTE PTR [esi],0
- ret
- FSY_SIGNEDOFS ENDP
- FSY_WORDOFS PROC
- mov eax,"+ow_"
- call put4
- mov eax,[edi + OPERAND.ADDRESS]
- call PutDword
- mov BYTE PTR [esi],0
- ret
- FSY_WORDOFS ENDP
- FSY_BYTEOFS PROC
- mov eax,"+ob_"
- call put4
- mov eax,[edi + OPERAND.ADDRESS]
- call PutByte
- mov BYTE PTR [esi],0
- ret
- FSY_BYTEOFS ENDP
- FSY_ABSOLUTE PROC
- mov eax,"ab_"
- call put3
- mov eax,[edi + OPERAND.ADDRESS]
- call PutDword
- mov BYTE PTR [esi],0
- ret
- FSY_ABSOLUTE ENDP
- FSY_SIGNEDIMM PROC
- bt [edi + OPERAND.ADDRESS],31
- mov eax,"+is_"
- jnc fsi_pos
- mov eax,"-is_"
- fsi_pos:
- call put4
- mov eax,[edi + OPERAND.ADDRESS]
- call ABSX
- call PutByte
- mov BYTE PTR [esi],0
- ret
- FSY_SIGNEDIMM ENDP
- FSY_WORDIMM PROC
- mov eax,"iw_"
- call put3
- mov eax,[edi + OPERAND.ADDRESS]
- call PutDword
- mov BYTE PTR [esi],0
- ret
- FSY_WORDIMM ENDP
- FSY_BYTEIMM PROC
- mov eax,"ib_"
- call put3
- mov eax,[edi + OPERAND.ADDRESS]
- call PutByte
- mov BYTE PTR [esi],0
- ret
- FSY_BYTEIMM ENDP
- FSY_PORT PROC
- mov eax,"p_"
- call put2
- mov eax,[edi + OPERAND.ADDRESS]
- call PutByte
- mov BYTE PTR [esi],0
- ret
- FSY_PORT ENDP
- FSY_INTR PROC
- mov eax,"it_"
- call put3
- mov eax,[edi + OPERAND.ADDRESS]
- call PutByte
- mov BYTE PTR [esi],0
- ret
- FSY_INTR ENDP
- FSY_RETURN PROC
- mov eax,"rt_"
- call put3
- mov eax,[edi + OPERAND.ADDRESS]
- call PutWord
- mov BYTE PTR [esi],0
- ret
- FSY_RETURN ENDP
- FSY_ABSBRANCH PROC
- mov eax,"ba_"
- call put3
- mov eax,[edi + OPERAND.ADDRESS]
- call PutDword
- mov BYTE PTR [esi],0
- ret
- FSY_ABSBRANCH ENDP
- FSY_LONGBRANCH PROC
- mov eax,"bl_"
- call put3
- mov eax,[edi + OPERAND.ADDRESS]
- call PutDword
- mov BYTE PTR [esi],0
- ret
- FSY_LONGBRANCH ENDP
- FSY_SHORTBRANCH PROC
- mov eax,"bs_"
- call put3
- mov eax,[edi + OPERAND.ADDRESS]
- call PutDword
- mov BYTE PTR [esi],0
- ret
- FSY_SHORTBRANCH ENDP
- FSY_SHIFT PROC
- mov eax,"ib_"
- call put3
- mov eax,[edi + OPERAND.ADDRESS]
- call PutByte
- mov BYTE PTR [esi],0
- ret
- FSY_SHIFT ENDP
- FSY_SEGMENT PROC
- mov eax,"sg_"
- call put3
- mov ax,[edi + OPERAND.OESEG]
- call PutWord
- mov BYTE PTR [esi],0
- ret
- FSY_SEGMENT ENDP
- FormatValue PROC
- dec al
- push 0
- call TableDispatch
- dd 14
- dd FSY_SIGNEDOFS,FSY_WORDOFS,FSY_BYTEOFS,FSY_ABSOLUTE
- dd FSY_SIGNEDIMM,FSY_WORDIMM,FSY_BYTEIMM,FSY_PORT
- dd FSY_INTR,FSY_RETURN,FSY_ABSBRANCH,FSY_LONGBRANCH
- dd FSY_SHORTBRANCH,FSY_SHIFT,FSY_SEGMENT
- ret
- FormatValue ENDP
- END