comment ~ ==================================================================
Copyright (c) Adam Seychell, 1994
You may use this source code in any way you wish provided that the
following conditions are met;
1) Any software what uses any part of this program must be for
for non-profitable use.
2) Send me a copy of improvments you have made to the debugger.
I have released the source in the hope it will be useful. The debugger
source code may be used or improved by others who are interested in
debeloping thier own. This source code is written in MASM 6.1 and by
no means is it written neatly. If someone wants to write thier
own debugger then best thing would be to use the instruction decode
routine ( DEBUG.INC ) since this is a general routine for displaying
486 instructions as a string. The rest of the debugger could be written
in 32bit C/C++ and while still using ASM for the exception handlers.
~
;============================================================================
;
;
; A routine that decodes an instrucion and outputs it in a string
;
;
;
; FUNCTION: Decode_instruction
;
; EXPECTS: ESI pointing to the instruction
; EDI pointing to the output string buffer
;
;
;
; RETURNS: * EDI pointing the the last character in the string
; (string also terminates with zero character).
; * ESI pointing to next instruction.
; * If the inscruction was invalid then Carry is set and
; ESI is unchanged, otherwise carry is clear.
;
; [MOD_RM_flag] = non zero if insrcuction contains a
; address operand.
; [op_seg_overide] = points segment override symbol string.
; or NULL if not exsits
; [MOD_RM_DefaultSegmentReg] = points default segment override string.
;
;
;=============================================================================
NoOp EQU 99
Symbol EQU 100
NULL EQU 0
NULLL EQU 102
immediate_data EQU 110
unsigned_full_offset EQU 112
offset_selector EQU 113
mod_zxreg_rm EQU 114
reg_eax EQU 115
port_DX_IN EQU 116
port_number_IN EQU 117
port_DX_OUT EQU 118
port_number_OUT EQU 119
mod_reg_rm EQU 120
mod_sreg3_rm EQU 121
mod_sreg2_rm EQU 122
opcode_mask_vlaues LABEL Byte
TTTTTTTT EQU 180
db 11111111b
TTTTTTTw EQU 181
db 11111110b
TTTTTTdw EQU 182
db 11111100b
TTTTTTsw EQU 183
db 11111100b
TTTTTreg EQU 184
db 11111000b
TTTTTTsT EQU 185
db 11111101b
TTTTwreg EQU 186
db 11110000b
TTT_sreg2_TTT EQU 187
db 11100111b
TT_sreg3_TTT EQU 188
db 11000111b
TTTTTTdT EQU 189
db 11111101b
TT_CR0_reg EQU 190
db 11000000b
TT_DR0_reg EQU 191
db 11000000b
TT_TR0_reg EQU 192
db 11000000b
mod_TTT_rm EQU 193
db 00111000b
the_last_T EQU 194
REG_CL EQU 150
immediate_8bit EQU 151
SetEndCharTo_W EQU 152
full_displacement EQU 153
Short_displacement EQU 154
full_offset_selector EQU 155
immediate_16bit EQU 156
REP_prefix EQU 157
Set_direc EQU 158
DS_overide EQU 200
ES_overide EQU 201
FS_overide EQU 202
GS_overide EQU 203
SS_overide EQU 204
CS_overide EQU 205
The_486_Instruction_Table LABEL BYTE
;
; I havn't check to make sure all of these intruction formats are correct,
; but I was very carful when I typed them in. It took me bloody days!
;
db Symbol, 'mov '
db TTTTTTdw, mod_reg_rm ,NULLL,NULLL
db 10001000b ,NoOp,NoOp
db TTTTTTTw, mod_TTT_rm, immediate_data ,NULLL
db 11000110b, 00000000b ,NoOp
db TTTTwreg, immediate_data ,NULLL,NULLL
db 10110000b ,NoOp,NoOp
db TTTTTTTw, reg_eax, Unsigned_full_offset ,NULLL
db 10100000b ,NoOp,NoOp
db TTTTTTTw, Unsigned_full_offset, Reg_eax ,NULLL
db 10100010b ,NoOp,NoOp
db TTTTTTdT, mod_sreg3_rm ,NULLL,NULLL
db 10001100b ,NoOp,NoOp
db TTTTTTTT , TTTTTTdT ,TT_CR0_reg ,NULLL
db 00001111b, 00100000b,11000000b
db TTTTTTTT , TTTTTTdT ,TT_DR0_reg ,NULLL
db 00001111b, 00100001b,11000000b
db TTTTTTTT , TTTTTTdT ,TT_TR0_reg ,NULLL
db 00001111b, 00100100b,11000000b
db Symbol, 'movsx '
db TTTTTTTT, TTTTTTTw, mod_zxreg_rm ,NULLL
db 00001111b, 10111110b ,NoOp
db Symbol, 'movzx '
db TTTTTTTT, TTTTTTTw, mod_zxreg_rm ,NULLL
db 00001111b, 10110110b ,NoOp
db Symbol, 'push '
db TTTTTTTT, mod_TTT_rm ,NULLL,NULLL
db 11111111b, 00110000b ,NoOp
db TTTTTreg ,NULLL,NULLL,NULLL
db 01010000b ,NoOp,NoOp
db TTT_sreg2_TTT ,NULLL,NULLL,NULLL
db 00000110b ,NoOp,NoOp
db TTTTTTTT, TT_sreg3_TTT ,NULLL,NULLL
db 00001111b, 10000000b ,NoOp
db TTTTTTsT, immediate_data ,NULLL,NULLL
db 01101000b ,NoOp,NoOp
db Symbol, 'pushad'
db TTTTTTTT ,NULLL,NULLL,NULLL
db 01100000b ,NoOp,NoOp
db Symbol, 'pop '
db TTTTTTTT, mod_TTT_rm ,NULLL,NULLL
db 10001111b, 00000000b ,NoOp
db TTTTTreg ,NULLL,NULLL,NULLL
db 01011000b ,NoOp,NoOp
db TTT_sreg2_TTT ,NULLL,NULLL,NULLL
db 00000111b ,NoOp,NoOp
db TTTTTTTT, TT_sreg3_TTT ,NULLL,NULLL
db 00001111b, 10000001b ,NoOp
db Symbol, 'popad '
db TTTTTTTT ,NULLL,NULLL,NULLL
db 01100001b ,NoOp,NoOp
db Symbol, 'in '
db TTTTTTTw, port_number_IN ,NULLL,NULLL
db 11100100b ,NoOp,NoOp
db TTTTTTTw, port_DX_IN ,NULLL,NULLL
db 11101100b ,NoOp,NoOp
db Symbol, 'out '
db TTTTTTTw, port_number_OUT ,NULLL,NULLL
db 11100110b ,NoOp,NoOp
db TTTTTTTw, port_DX_OUT ,NULLL,NULLL
db 11101110b ,NoOp,NoOp
db Symbol, 'lea '
db TTTTTTTT, Set_direc, mod_reg_rm ,NULLL
db 10001101b ,NoOp,NoOp
db Symbol, 'lds '
db TTTTTTTT, Set_direc, mod_reg_rm ,NULLL
db 11000101b ,NoOp,NoOp
db Symbol, 'les '
db TTTTTTTT, Set_direc, mod_reg_rm ,NULLL
db 11000100b ,NoOp,NoOp
db Symbol, 'lfs '
db TTTTTTTT, TTTTTTTT, Set_direc, mod_reg_rm
db 00001111b, 10110100b ,NoOp
db Symbol, 'lgs '
db TTTTTTTT, TTTTTTTT, Set_direc, mod_reg_rm
db 00001111b, 10110101b ,NoOp
db Symbol, 'lss '
db TTTTTTTT, TTTTTTTT, Set_direc, mod_reg_rm
db 00001111b, 10110010b ,NoOp
db Symbol, 'clc '
db TTTTTTTT ,NULLL,NULLL,NULLL
db 11111000b ,NoOp,NoOp
db Symbol, 'cld '
db TTTTTTTT ,NULLL,NULLL,NULLL
db 11111100b ,NoOp,NoOp
db Symbol, 'cli '
db TTTTTTTT ,NULLL,NULLL,NULLL
db 11111010b ,NoOp,NoOp
db Symbol, 'clts '
db TTTTTTTT, TTTTTTTT ,NULLL ,NULLL
db 00001111b,00000110b ,NoOp
db Symbol, 'cmc '
db TTTTTTTT ,NULLL,NULLL,NULLL
db 11110101b ,NoOp,NoOp
db Symbol, 'lahf '
db TTTTTTTT ,NULLL,NULLL,NULLL
db 10011111b ,NoOp,NoOp
db Symbol, 'popf '
db TTTTTTTT ,NULLL,NULLL,NULLL
db 10011101b ,NoOp,NoOp
db Symbol, 'pushf '
db TTTTTTTT ,NULLL,NULLL,NULLL
db 10011100b ,NoOp,NoOp
db Symbol, 'sahf '
db TTTTTTTT ,NULLL,NULLL,NULLL
db 10011110b ,NoOp,NoOp
db Symbol, 'stc '
db TTTTTTTT ,NULLL,NULLL,NULLL
db 11111001b ,NoOp,NoOp
db Symbol, 'std '
db TTTTTTTT ,NULLL,NULLL,NULLL
db 11111101b ,NoOp,NoOp
db Symbol, 'sti '
db TTTTTTTT ,NULLL,NULLL,NULLL
db 11111011b ,NoOp,NoOp
db Symbol, 'add '
db TTTTTTdw, mod_reg_rm ,NULLL,NULLL
db 00000000b ,NoOp,NoOp
db TTTTTTsw, mod_TTT_rm , immediate_data ,NULLL
db 10000000b, 00000000b ,NoOp
db TTTTTTTw, reg_eax, immediate_data ,NULLL
db 00000100b ,NoOp,NoOp
db Symbol, 'adc '
db TTTTTTdw, mod_reg_rm ,NULLL,NULLL
db 00010000b ,NoOp,NoOp
db TTTTTTsw, mod_TTT_rm , immediate_data ,NULLL
db 10000000b, 00010000b ,NoOp
db TTTTTTTw, reg_eax, immediate_data ,NULLL
db 00010100b ,NoOp,NoOp
db Symbol, 'inc '
db TTTTTTTw, mod_TTT_rm ,NULLL,NULLL
db 11111110b, 00000000b ,NoOp
db TTTTTreg ,NULLL,NULLL,NULLL
db 01000000b ,NoOp,NoOp
db Symbol, 'dec '
db TTTTTTTw, mod_TTT_rm ,NULLL,NULLL
db 11111110b, 00001000b ,NoOp
db TTTTTreg ,NULLL,NULLL,NULLL
db 01001000b ,NoOp,NoOp
db Symbol, 'sub '
db TTTTTTdw, mod_reg_rm ,NULLL,NULLL
db 00101000b ,NoOp,NoOp
db TTTTTTsw, mod_TTT_rm , immediate_data ,NULLL
db 10000000b, 00101000b ,NoOp
db TTTTTTTw, reg_eax, immediate_data ,NULLL
db 00101100b ,NoOp,NoOp
db Symbol, 'sbb '
db TTTTTTdw, mod_reg_rm ,NULLL,NULLL
db 00011000b ,NoOp,NoOp
db TTTTTTsw, mod_TTT_rm , immediate_data ,NULLL
db 10000000b, 00011000b ,NoOp
db TTTTTTTw, reg_eax, immediate_data ,NULLL
db 00011100b ,NoOp,NoOp
db Symbol, 'cmp '
db TTTTTTdw, mod_reg_rm ,NULLL,NULLL
db 00111000b ,NoOp,NoOp
db TTTTTTsw, mod_TTT_rm , immediate_data ,NULLL
db 10000000b, 00111000b ,NoOp
db TTTTTTTw, reg_eax, immediate_data ,NULLL
db 00111100b ,NoOp,NoOp
db Symbol, 'neg '
db TTTTTTTw, mod_TTT_rm ,NULLL,NULLL
db 11110110b, 00011000b ,NoOp
db Symbol, 'aaa '
db TTTTTTTT ,NULLL,NULLL,NULLL
db 00110111b ,NoOp,NoOp
db Symbol, 'aas '
db TTTTTTTT ,NULLL,NULLL,NULLL
db 00111111b ,NoOp,NoOp
db Symbol, 'daa '
db TTTTTTTT ,NULLL,NULLL,NULLL
db 00100111b ,NoOp,NoOp
db Symbol, 'das '
db TTTTTTTT ,NULLL,NULLL,NULLL
db 00101111b ,NoOp,NoOp
db Symbol, 'mul '
db TTTTTTTw, mod_TTT_rm ,NULLL,NULLL
db 11110110b, 00100000b ,NoOp
db Symbol, 'imul '
db TTTTTTTw, mod_TTT_rm ,NULLL,NULLL
db 11110110b, 00101000b ,NoOp
db TTTTTTTT, TTTTTTTT, Set_direc, mod_reg_rm
db 00001111b, 10101111b ,NoOp
db TTTTTTsT, Set_direc, mod_reg_rm ,immediate_data
db 01101001b ,NoOp,NoOp
db Symbol, 'div '
db TTTTTTTw, mod_TTT_rm ,NULLL,NULLL
db 11110110b, 00110000b ,NoOp
db Symbol, 'idiv '
db TTTTTTTw, mod_TTT_rm ,NULLL,NULLL
db 11110110b, 00111000b ,NoOp
db Symbol, 'aad '
db TTTTTTTT, TTTTTTTT ,NULLL,NULLL
db 11010101b, 00001010b ,NoOp
db Symbol, 'aam '
db TTTTTTTT, TTTTTTTT ,NULLL,NULLL
db 11010100b, 00001010b ,NoOp
db Symbol, 'cwde '
db TTTTTTTT ,NULLL,NULLL,NULLL
db 10011000b ,NoOp,NoOp
db Symbol, 'cdq '
db TTTTTTTT ,NULLL,NULLL,NULLL
db 10011001b ,NoOp,NoOp
db Symbol, 'rol '
db TTTTTTTw, mod_TTT_rm ,NULLL,NULLL
db 11010000b, 00000000b ,NoOp
db TTTTTTTw, mod_TTT_rm , REG_CL ,NULLL
db 11010010b, 00000000b ,NoOp
db TTTTTTTw, mod_TTT_rm , immediate_8bit ,NULLL
db 11000000b, 00000000b ,NoOp
db Symbol, 'ror '
db TTTTTTTw, mod_TTT_rm ,NULLL,NULLL
db 11010000b, 00001000b ,NoOp
db TTTTTTTw, mod_TTT_rm , REG_CL ,NULLL
db 11010010b, 00001000b ,NoOp
db TTTTTTTw, mod_TTT_rm , immediate_8bit ,NULLL
db 11000000b, 00001000b ,NoOp
db Symbol, 'rcl '
db TTTTTTTw, mod_TTT_rm ,NULLL,NULLL
db 11010000b, 00010000b ,NoOp
db TTTTTTTw, mod_TTT_rm , REG_CL ,NULLL
db 11010010b, 00010000b ,NoOp
db TTTTTTTw, mod_TTT_rm , immediate_8bit ,NULLL
db 11000000b, 00010000b ,NoOp
db Symbol, 'rcr '
db TTTTTTTw, mod_TTT_rm ,NULLL,NULLL
db 11010000b, 00011000b ,NoOp
db TTTTTTTw, mod_TTT_rm , REG_CL ,NULLL
db 11010010b, 00011000b ,NoOp
db TTTTTTTw, mod_TTT_rm , immediate_8bit ,NULLL
db 11000000b, 00011000b ,NoOp
db Symbol, 'shl '
db TTTTTTTw, mod_TTT_rm ,NULLL,NULLL
db 11010000b, 00100000b ,NoOp
db TTTTTTTw, mod_TTT_rm , REG_CL ,NULLL
db 11010010b, 00100000b ,NoOp
db TTTTTTTw, mod_TTT_rm , immediate_8bit ,NULLL
db 11000000b, 00100000b ,NoOp
db Symbol, 'shr '
db TTTTTTTw, mod_TTT_rm ,NULLL,NULLL
db 11010000b, 00101000b ,NoOp
db TTTTTTTw, mod_TTT_rm , REG_CL ,NULLL
db 11010010b, 00101000b ,NoOp
db TTTTTTTw, mod_TTT_rm , immediate_8bit ,NULLL
db 11000000b, 00101000b ,NoOp
db Symbol, 'sal '
db TTTTTTTw, mod_TTT_rm ,NULLL,NULLL
db 11010000b, 00110000b ,NoOp
db TTTTTTTw, mod_TTT_rm , REG_CL ,NULLL
db 11010010b, 00110000b ,NoOp
db TTTTTTTw, mod_TTT_rm , immediate_8bit ,NULLL
db 11000000b, 00110000b ,NoOp
db Symbol, 'sar '
db TTTTTTTw, mod_TTT_rm ,NULLL,NULLL
db 11010000b, 00111000b ,NoOp
db TTTTTTTw, mod_TTT_rm , REG_CL ,NULLL
db 11010010b, 00111000b ,NoOp
db TTTTTTTw, mod_TTT_rm , immediate_8bit ,NULLL
db 11000000b, 00111000b ,NoOp
db Symbol, 'shld '
db TTTTTTTT, TTTTTTTT, mod_reg_rm, immediate_8bit
db 00001111b, 10100100b ,NoOp
db TTTTTTTT, TTTTTTTT, mod_reg_rm ,reg_CL
db 00001111b, 10100101b ,NoOp
db Symbol, 'shrd '
db TTTTTTTT, TTTTTTTT, mod_reg_rm, immediate_8bit
db 00001111b, 10101100b ,NoOp
db TTTTTTTT, TTTTTTTT, mod_reg_rm ,reg_CL
db 00001111b, 10101101b ,NoOp
db Symbol, 'test '
db TTTTTTTw, mod_reg_rm ,NULLL ,NULLL
db 10000100b ,NoOp,NoOp
db TTTTTTTw, mod_TTT_rm ,immediate_data ,NULLL
db 11110110b, 00000000b ,NoOp
db TTTTTTTw, reg_EAX ,immediate_data ,NULLL
db 10101000b ,NoOp,NoOp
db Symbol, 'and '
db TTTTTTdw, mod_reg_rm ,NULLL,NULLL
db 00100000b ,NoOp,NoOp
db TTTTTTsw, mod_TTT_rm ,immediate_data ,NULLL
db 10000000b, 00100000b ,NoOp
db TTTTTTTw, reg_EAX ,immediate_data ,NULLL
db 00100100b ,NoOp,NoOp
db Symbol, 'or '
db TTTTTTdw, mod_reg_rm ,NULLL,NULLL
db 00001000b ,NoOp,NoOp
db TTTTTTsw, mod_TTT_rm ,immediate_data ,NULLL
db 10000000b, 00001000b ,NoOp
db TTTTTTTw, reg_EAX ,immediate_data ,NULLL
db 00001100b ,NoOp,NoOp
db Symbol, 'xor '
db TTTTTTdw, mod_reg_rm ,NULLL,NULLL
db 00110000b ,NoOp,NoOp
db TTTTTTsw, mod_TTT_rm ,immediate_data ,NULLL
db 10000000b, 00110000b ,NoOp
db TTTTTTTw, reg_EAX ,immediate_data ,NULLL
db 00110100b ,NoOp,NoOp
db Symbol, 'not '
db TTTTTTTw, mod_TTT_rm ,NULLL,NULLL
db 11110110b, 00010000b ,NoOp
db Symbol, 'cmps '
db TTTTTTTw ,SetEndCharTo_W ,NULLL,NULLL
db 10100110b ,NoOp,NoOp
db Symbol, 'ins '
db TTTTTTTw ,SetEndCharTo_W ,NULLL,NULLL
db 01101100b ,NoOp,NoOp
db Symbol, 'lods '
db TTTTTTTw ,SetEndCharTo_W ,NULLL,NULLL
db 10101100b ,NoOp,NoOp
db Symbol, 'movs '
db TTTTTTTw ,SetEndCharTo_W ,NULLL,NULLL
db 10100100b ,NoOp,NoOp
db Symbol, 'outs '
db TTTTTTTw ,SetEndCharTo_W ,NULLL,NULLL
db 01101110b ,NoOp,NoOp
db Symbol, 'scas '
db TTTTTTTw ,SetEndCharTo_W ,NULLL,NULLL
db 10101110b ,NoOp,NoOp
db Symbol, 'stos '
db TTTTTTTw ,SetEndCharTo_W ,NULLL,NULLL
db 10101010b ,NoOp,NoOp
db Symbol, 'xlat '
db TTTTTTTT ,NULLL,NULLL,NULLL
db 11010111b ,NoOp,NoOp
; ----------------- Bit manipulation ------------------------
db Symbol, 'bsf '
db TTTTTTTT , TTTTTTTT, Set_direc, mod_reg_rm
db 00001111b, 10111100b ,NoOp
db Symbol, 'bsr '
db TTTTTTTT , TTTTTTTT, Set_direc, mod_reg_rm
db 00001111b, 10111101b ,NoOp
db Symbol, 'bt '
db TTTTTTTT , TTTTTTTT, mod_TTT_rm, immediate_8bit
db 00001111b, 10111010b, 00100000b
db TTTTTTTT , TTTTTTTT, mod_reg_rm ,NULLL
db 00001111b, 10100011b ,NoOp
db Symbol, 'btc '
db TTTTTTTT , TTTTTTTT, mod_TTT_rm, immediate_8bit
db 00001111b, 10111010b, 00111000b
db TTTTTTTT , TTTTTTTT, mod_reg_rm ,NULLL
db 00001111b, 10111011b ,NoOp
db Symbol, 'btr '
db TTTTTTTT , TTTTTTTT, mod_TTT_rm, immediate_8bit
db 00001111b, 10111010b, 00110000b
db TTTTTTTT , TTTTTTTT, mod_reg_rm ,NULLL
db 00001111b, 10110011b ,NoOp
db Symbol, 'bts '
db TTTTTTTT , TTTTTTTT, mod_TTT_rm, immediate_8bit
db 00001111b, 10111010b, 00101000b
db TTTTTTTT , TTTTTTTT, mod_reg_rm ,NULLL
db 00001111b, 10101011b ,NoOp
; ----------------- Controll Transfer ------------------------
db Symbol, 'call '
db TTTTTTTT , full_displacement ,NULLL,NULLL
db 11101000b ,NoOp,NoOp
db TTTTTTTT , mod_TTT_rm ,NULLL,NULLL
db 11111111b, 00010000b ,NoOp
db TTTTTTTT , full_offset_selector ,NULLL,NULLL
db 10011010b ,NoOp,NoOp
db Symbol, 'call f'
db TTTTTTTT , mod_TTT_rm ,NULLL,NULLL
db 11111111b, 00011000b ,NoOp
db Symbol, 'jmp '
db TTTTTTTT , Short_displacement ,NULLL,NULLL
db 11101011b ,NoOp,NoOp
db TTTTTTTT , full_displacement ,NULLL,NULLL
db 11101001b ,NoOp,NoOp
db TTTTTTTT , mod_TTT_rm ,NULLL,NULLL
db 11111111b, 00100000b ,NoOp
db TTTTTTTT , full_offset_selector ,NULLL,NULLL
db 11101010b ,NoOp,NoOp
db Symbol, 'jmp f'
db TTTTTTTT , mod_TTT_rm ,NULLL,NULLL
db 11111111b, 00101000b ,NoOp
db Symbol, 'ret '
db TTTTTTTT ,NULLL,NULLL,NULLL
db 11000011b ,NoOp,NoOp
db TTTTTTTT , immediate_16bit ,NULLL,NULLL
db 11000010b ,NoOp,NoOp
db Symbol, 'ret f'
db TTTTTTTT ,NULLL,NULLL,NULLL
db 11001011b ,NoOp,NoOp
db TTTTTTTT , immediate_16bit ,NULLL,NULLL
db 11001010b ,NoOp,NoOp
db Symbol, 'jo '
db TTTTTTTT , Short_displacement ,NULLL,NULLL
db 01110000b ,NoOp,NoOp
db TTTTTTTT , TTTTTTTT, full_displacement ,NULLL
db 00001111b, 10000000b ,NoOp
db Symbol, 'jno '
db TTTTTTTT , Short_displacement ,NULLL,NULLL
db 01110001b ,NoOp,NoOp
db TTTTTTTT , TTTTTTTT, full_displacement ,NULLL
db 00001111b, 10000001b ,NoOp
db Symbol, 'jb '
db TTTTTTTT , Short_displacement ,NULLL,NULLL
db 01110010b ,NoOp,NoOp
db TTTTTTTT , TTTTTTTT, full_displacement ,NULLL
db 00001111b, 10000010b ,NoOp
db Symbol, 'jae '
db TTTTTTTT , Short_displacement ,NULLL,NULLL
db 01110011b ,NoOp,NoOp
db TTTTTTTT , TTTTTTTT, full_displacement ,NULLL
db 00001111b, 10000011b ,NoOp
db Symbol, 'jz '
db TTTTTTTT , Short_displacement ,NULLL,NULLL
db 01110100b ,NoOp,NoOp
db TTTTTTTT , TTTTTTTT, full_displacement ,NULLL
db 00001111b, 10000100b ,NoOp
db Symbol, 'jnz '
db TTTTTTTT , Short_displacement ,NULLL,NULLL
db 01110101b ,NoOp,NoOp
db TTTTTTTT , TTTTTTTT, full_displacement ,NULLL
db 00001111b, 10000101b ,NoOp
db Symbol, 'jbe '
db TTTTTTTT , Short_displacement ,NULLL,NULLL
db 01110110b ,NoOp,NoOp
db TTTTTTTT , TTTTTTTT, full_displacement ,NULLL
db 00001111b, 10000110b ,NoOp
db Symbol, 'ja '
db TTTTTTTT , Short_displacement ,NULLL,NULLL
db 01110111b ,NoOp,NoOp
db TTTTTTTT , TTTTTTTT, full_displacement ,NULLL
db 00001111b, 10000111b ,NoOp
db Symbol, 'js '
db TTTTTTTT , Short_displacement ,NULLL,NULLL
db 01111000b ,NoOp,NoOp
db TTTTTTTT , TTTTTTTT, full_displacement ,NULLL
db 00001111b, 10001000b ,NoOp
db Symbol, 'jns '
db TTTTTTTT , Short_displacement ,NULLL,NULLL
db 01111001b ,NoOp,NoOp
db TTTTTTTT , TTTTTTTT, full_displacement ,NULLL
db 00001111b, 10001001b ,NoOp
db Symbol, 'jpe '
db TTTTTTTT , Short_displacement ,NULLL,NULLL
db 01111010b ,NoOp,NoOp
db TTTTTTTT , TTTTTTTT, full_displacement ,NULLL
db 00001111b, 10001010b ,NoOp
db Symbol, 'jno '
db TTTTTTTT , Short_displacement ,NULLL,NULLL
db 01111011b ,NoOp,NoOp
db TTTTTTTT , TTTTTTTT, full_displacement ,NULLL
db 00001111b, 10001011b ,NoOp
db Symbol, 'jl '
db TTTTTTTT , Short_displacement ,NULLL,NULLL
db 01111100b ,NoOp,NoOp
db TTTTTTTT , TTTTTTTT, full_displacement ,NULLL
db 00001111b, 10001100b ,NoOp
db Symbol, 'jge '
db TTTTTTTT , Short_displacement ,NULLL,NULLL
db 01111101b ,NoOp,NoOp
db TTTTTTTT , TTTTTTTT, full_displacement ,NULLL
db 00001111b, 10001101b ,NoOp
db Symbol, 'jle '
db TTTTTTTT , Short_displacement ,NULLL,NULLL
db 01111110b ,NoOp,NoOp
db TTTTTTTT , TTTTTTTT, full_displacement ,NULLL
db 00001111b, 10001110b ,NoOp
db Symbol, 'jg '
db TTTTTTTT , Short_displacement ,NULLL,NULLL
db 01111111b ,NoOp,NoOp
db TTTTTTTT , TTTTTTTT, full_displacement ,NULLL
db 00001111b, 10001111b ,NoOp
db Symbol, 'jecxz '
db TTTTTTTT , Short_displacement ,NULLL,NULLL
db 11100011b ,NoOp,NoOp
db Symbol, 'loopnz'
db TTTTTTTT , Short_displacement ,NULLL,NULLL
db 11100000b ,NoOp,NoOp
db Symbol, 'loop '
db TTTTTTTT , Short_displacement ,NULLL,NULLL
db 11100010b ,NoOp,NoOp
db Symbol, 'loopz '
db TTTTTTTT , Short_displacement ,NULLL,NULLL
db 11100001b ,NoOp,NoOp
;-------------- conditional byte set ------------------------
db Symbol, 'seto '
db TTTTTTTT , TTTTTTTT, mod_TTT_rm ,NULLL
db 00001111b, 10010000b, 00000000b
db Symbol, 'setno '
db TTTTTTTT , TTTTTTTT, mod_TTT_rm ,NULLL
db 00001111b, 10010001b, 00000000b
db Symbol, 'setb '
db TTTTTTTT , TTTTTTTT, mod_TTT_rm ,NULLL
db 00001111b, 10010010b, 00000000b
db Symbol, 'setae '
db TTTTTTTT , TTTTTTTT, mod_TTT_rm ,NULLL
db 00001111b, 10010011b, 00000000b
db Symbol, 'setz '
db TTTTTTTT , TTTTTTTT, mod_TTT_rm ,NULLL
db 00001111b, 10010100b, 00000000b
db Symbol, 'setnz '
db TTTTTTTT , TTTTTTTT, mod_TTT_rm ,NULLL
db 00001111b, 10010101b, 00000000b
db Symbol, 'setbe '
db TTTTTTTT , TTTTTTTT, mod_TTT_rm ,NULLL
db 00001111b, 10010110b, 00000000b
db Symbol, 'seta '
db TTTTTTTT , TTTTTTTT, mod_TTT_rm ,NULLL
db 00001111b, 10010111b, 00000000b
db Symbol, 'sets '
db TTTTTTTT , TTTTTTTT, mod_TTT_rm ,NULLL
db 00001111b, 10011000b, 00000000b
db Symbol, 'setns '
db TTTTTTTT , TTTTTTTT, mod_TTT_rm ,NULLL
db 00001111b, 10011001b, 00000000b
db Symbol, 'setpe '
db TTTTTTTT , TTTTTTTT, mod_TTT_rm ,NULLL
db 00001111b, 10011010b, 00000000b
db Symbol, 'setpo '
db TTTTTTTT , TTTTTTTT, mod_TTT_rm ,NULLL
db 00001111b, 10011011b, 00000000b
db Symbol, 'setl '
db TTTTTTTT , TTTTTTTT, mod_TTT_rm ,NULLL
db 00001111b, 10011100b, 00000000b
db Symbol, 'setge '
db TTTTTTTT , TTTTTTTT, mod_TTT_rm ,NULLL
db 00001111b, 10011101b, 00000000b
db Symbol, 'setle '
db TTTTTTTT , TTTTTTTT, mod_TTT_rm ,NULLL
db 00001111b, 10011110b, 00000000b
db Symbol, 'setg '
db TTTTTTTT , TTTTTTTT, mod_TTT_rm ,NULLL
db 00001111b, 10011111b, 00000000b
db Symbol, 'enter '
db TTTTTTTT , immediate_16bit ,immediate_8bit ,NULLL
db 11001000b ,NoOp,NoOp
db Symbol, 'leave '
db TTTTTTTT ,NULLL,NULLL,NULLL
db 11001001b ,NoOp,NoOp
db Symbol, 'int '
db TTTTTTTT , immediate_8bit ,NULLL,NULLL
db 11001101b ,NoOp,NoOp
db Symbol, 'INTĂș3 '
db TTTTTTTT ,NULLL,NULLL,NULLL
db 11001100b ,NoOp,NoOp
db Symbol, 'into '
db TTTTTTTT ,NULLL,NULLL,NULLL
db 11001110b ,NoOp,NoOp
db Symbol, 'bound '
db TTTTTTTT , Set_Direc, mod_reg_rm ,NULLL
db 01100010b ,NoOp,NoOp
db Symbol, 'iret '
db TTTTTTTT , SetEndCharTo_W ,NULLL,NULLL
db 11001111b ,NoOp,NoOp
db Symbol, 'hlt '
db TTTTTTTT ,NULLL,NULLL,NULLL
db 11110100b ,NoOp,NoOp
db Symbol, 'nop '
db TTTTTTTT ,NULLL,NULLL,NULLL
db 10010000b ,NoOp,NoOp
db Symbol, 'wait '
db TTTTTTTT ,NULLL,NULLL,NULLL
db 10011011b ,NoOp,NoOp
db Symbol, 'arpl '
db TTTTTTTT , mod_reg_rm ,NULLL,NULLL
db 01100011b ,NoOp,NoOp
db Symbol, 'lar '
db TTTTTTTT , TTTTTTTT ,Set_Direc, mod_reg_rm
db 00001111b, 00000010b ,NoOp
db Symbol, 'lgdt '
db TTTTTTTT , TTTTTTTT ,mod_TTT_rm ,NULLL
db 00001111b, 00000001b, 00010000b
db Symbol, 'lidt '
db TTTTTTTT , TTTTTTTT ,mod_TTT_rm ,NULLL
db 00001111b, 00000001b, 00011000b
db Symbol, 'lldt '
db TTTTTTTT , TTTTTTTT ,mod_TTT_rm ,NULLL
db 00001111b, 00000000b, 00010000b
db Symbol, 'lmsw '
db TTTTTTTT , TTTTTTTT ,mod_TTT_rm ,NULLL
db 00001111b, 00000001b, 00110000b
db Symbol, 'lsl '
db TTTTTTTT , TTTTTTTT ,Set_Direc, mod_reg_rm
db 00001111b, 00000011b ,NoOp
db Symbol, 'ltr '
db TTTTTTTT , TTTTTTTT ,mod_TTT_rm ,NULLL
db 00001111b, 00000000b, 00011000b
db Symbol, 'sgdt '
db TTTTTTTT , TTTTTTTT ,mod_TTT_rm ,NULLL
db 00001111b, 00000001b, 00000000b
db Symbol, 'sidt '
db TTTTTTTT , TTTTTTTT ,mod_TTT_rm ,NULLL
db 00001111b, 00000001b, 00001000b
db Symbol, 'sldt '
db TTTTTTTT , TTTTTTTT ,mod_TTT_rm ,NULLL
db 00001111b, 00000000b, 00000000b
db Symbol, 'smsw '
db TTTTTTTT , TTTTTTTT ,mod_TTT_rm ,NULLL
db 00001111b, 00000001b, 00100000b
db Symbol, 'str '
db TTTTTTTT , TTTTTTTT ,mod_TTT_rm ,NULLL
db 00001111b, 00000000b, 00001000b
db Symbol, 'verr '
db TTTTTTTT , TTTTTTTT ,mod_TTT_rm ,NULLL
db 00001111b, 00000000b, 00100000b
db Symbol, 'verw '
db TTTTTTTT , TTTTTTTT ,mod_TTT_rm ,NULLL
db 00001111b, 00000000b, 00101000b
db Symbol, 'xchg '
db TTTTTTTw, mod_reg_rm ,NULLL,NULLL
db 10000110b ,NoOp,NoOp
db TTTTTreg, reg_eax ,NULLL,NULLL
db 10010000b ,NoOp,NoOp
;------------- 486 instuctions -----------------------
db Symbol, 'bswap '
db TTTTTTTT, TTTTTreg ,NULLL,NULLL
db 00001111b,11001000b ,NoOp
db Symbol, 'xadd '
db TTTTTTTT, TTTTTTTw, mod_reg_rm ,NULLL
db 00001111b, 11000000b ,NoOp
db Symbol, 'cmpxch'
db TTTTTTTT, TTTTTTTw, mod_reg_rm ,NULLL
db 00001111b, 10110000b ,NoOp
;--------------- Floting Point Processor Instuctions ----------------
Instruction_Definitions_End EQU $
mod_rm_16bit LABEL BYTE
db 'bx+si$ '
db 'bx+di$ '
db 'bp+si$ '
db 'bp+di$ '
db 'si$ '
db 'di$ '
db 'bp$ '
db 'bx$ '
EAX_symb db 'eax$'
ECX_symb db 'ecx$'
EDX_symb db 'edx$'
EBX_symb db 'ebx$'
ESP_symb db 'esp$'
EBP_symb db 'ebp$'
ESI_symb db 'esi$'
EDI_symb db 'edi$'
EIP_symb db 'eip$'
al_symb db 'al$ '
cl_symb db 'cl$ '
dl_symb db 'dl$ '
bl_symb db 'bl$ '
ah_symb db 'ah$ '
ch_symb db 'ch$ '
dh_symb db 'dh$ '
bh_symb db 'bh$ '
ES_symb db 'es$ '
CS_symb db 'cs$ '
SS_symb db 'ss$ '
DS_symb db 'ds$ '
FS_symb db 'fs$ '
GS_symb db 'gs$ '
db '??$ '
db '??$ '
REPNZ_symb db 'repnz $'
REPZ_symb db 'rep $'
FAR_symb db 'ar $'
byte_ptr_symb db 'byte ptr $'
word_ptr_symb db 'word ptr $'
CR0_symb db 'CR0$'
CR1_symb db 'CR1$'
CR2_symb db 'CR2$'
CR3_symb db 'CR3$'
CR4_symb db 'CR4$'
CR5_symb db 'CR5$'
CR6_symb db 'CR6$'
CR7_symb db 'CR7$'
DR0_symb db 'DR0$'
DR1_symb db 'DR1$'
DR2_symb db 'DR2$'
DR3_symb db 'DR3$'
DR4_symb db 'DR4$'
DR5_symb db 'DR5$'
DR6_symb db 'DR6$'
DR7_symb db 'DR7$'
TR0_symb db 'TR0$'
TR1_symb db 'TR1$'
TR2_symb db 'TR2$'
TR3_symb db 'TR3$'
TR4_symb db 'TR4$'
TR5_symb db 'TR5$'
TR6_symb db 'TR6$'
TR7_symb db 'TR7$'
instruc_CBW db 'cbw $'
instruc_CWD db 'cwd $'
op_seg_overide dd 0
reg_size db 0
op_direc db 0
op_sine db 0
op_was_done db 0
force_16bitReg db 0
addr_size_prefix db 0
op_size_prefix db 0
StringBufferPTR dd 0
char_position db 0
Decode_instruction PROC PRIVATE USES EAX EBX ECX EDX
LOCAL THE_symbol,old_ESI :dword
local format_ends :Dword
cld
mov StringBufferPTR,edi
mov char_position,0
mov op_seg_overide,NULL
mov addr_size_prefix,0
mov op_size_prefix,0
mov op_was_done,0
mov reg_size,1
mov op_direc,0
mov force_16bitreg,0
mov op_sine,0
mov old_ESI,esi
mov MOD_RM_flag,False
mov MOD_RM_EffectiveAddress,0
mov MOD_RM_size,2
mov MOD_RM_SegmentReg,00111110b
mov MOD_RM_DefaultSegmentReg,offset DS_symb
mov ecx,5
prefix_find_loop:
;------------- Get segment overide prefixes ---------
mov al,[esi]
.if al == 00101110b
mov op_seg_overide,offset CS_symb
mov MOD_RM_SegmentReg,al
.elseif al == 00111110b
mov op_seg_overide,offset DS_symb
mov MOD_RM_SegmentReg,al
.elseif al == 00100110b
mov op_seg_overide,offset ES_symb
mov MOD_RM_SegmentReg,al
.elseif al == 01100100b
mov op_seg_overide,offset FS_symb
mov MOD_RM_SegmentReg,al
.elseif al == 01100101b
mov op_seg_overide,offset GS_symb
mov MOD_RM_SegmentReg,al
.elseif al == 00110110b
mov op_seg_overide,offset SS_symb
mov MOD_RM_SegmentReg,al
.else
dec esi
.endif
inc esi
;------------ plot REPNZ/REPZ pefixes ------------
.if al == 11110010b
mov edx,offset REPNZ_symb
call string
inc esi
.elseif al == 11110011b
mov edx,offset REPZ_symb
call string
inc esi
.endif
;------------ get size prefixes -------------------
mov al,[esi]
.if al == 01100111b
mov addr_size_prefix,1
inc esi
.elseif al == 01100110b
mov op_size_prefix,1
inc esi
.endif
dec ecx
jnz prefix_find_loop
;---------- get the instruction ------------
mov edi,offset The_486_Instruction_Table
xor ebx,ebx
Find_What_Loop:
.if edi == Instruction_Definitions_End
mov al,'?'
call Print_char
mov esi,old_ESI
inc esi
movzx edi,char_position
add edi,StringBufferPTR
mov byte ptr [edi],0
stc
ret
.endif
.if byte ptr [edi] == Symbol
inc edi
mov THE_symbol,edi
add edi,6
.endif
push edi
push esi
CheckInstr_Loop:
mov al,[esi]
mov BL,[edi]
sub bl,TTTTTTTT
cmp bl ,( the_last_T - TTTTTTTT)
jae finished_it
and al,opcode_mask_vlaues[ebx] ; mask the instruction opcode
cmp al,[edi+4] ; compare with the opcode
jne contSrch_
inc edi ; instruction table pointer
inc esi ; instruction pointer
jmp checkInstr_Loop
contSrch_: pop esi
pop edi
contSrch: add edi,7
jmp Find_What_Loop
finished_it: ; finishe searching instruction
pop esi
pop edi
cmp byte ptr [esi],0fh
jne @f
cmp byte ptr [edi+1],NULLL
je contSrch
@@:
;===============================================
;--------- plot the instuction symbol on the screen ---------
push esi
mov esi,THE_symbol
.IF op_size_prefix == 1
.IF dword ptr [esi] == ' qdc'
mov edx,offset instruc_CWD
call string
jmp InstPrnted
.ELSEIF dword ptr [esi] == 'edwc'
mov edx,offset instruc_CBW
call string
jmp InstPrnted
.ENDIF
.ENDIF
mov ecx,6
.Repeat
lodsb
call Print_Char
.UntilCXZ
.if byte ptr [edi-1] == 'f'
mov edx,offset far_symb
call string
mov MOD_RM_size,3
.endif
InstPrnted:
pop esi
; EDI = OFFSET OF THE INSTRUC NULLL
mov format_ends,edi
add format_ends,4
Operand_decode_loop:
;---------- decode the operands ---------------------
mov al,[esi]
mov bl,[edi]
.IF BL == TTTTTTTw
and al,1
mov reg_size,al
.ELSEIF BL == TTTTTreg
call Plot_reg_field
.ELSEIF BL == TTTTTTdw
mov reg_size,al
and reg_size,1
shr al,1
and al,1
mov op_direc,al
.ELSEIF BL == TTTTTTdT
shr al,1
and al,1
mov op_direc,al
.ELSEIF BL == Set_direc
mov op_direc,1
dec esi
.ELSEIF BL == TTTTwreg
shr al,3
and al,1
mov reg_size,al
mov al,[esi]
call Plot_reg_field
.ELSEIF BL == TTTTTTsT
shr al,1
and al,1
mov op_sine,al
.ELSEIF BL == TTTTTTsw
mov reg_size,al
and reg_size,1
shr al,1
and al,1
mov op_sine,al
.ELSEIF BL == REG_CL
call Print_comma
mov edx,offset CL_symb
call string
DEC ESI
.ELSEIF BL == REG_EAX
call Print_comma
xor al,al
call Plot_reg_field
DEC ESI
.ELSEIF BL == SetEndCharTo_W
DEC ESI
sub char_position,2
mov al,'b'
.if reg_size == 1
.if op_size_prefix == 1
mov al,'w'
.if byte ptr [esi] == 11001111b
mov al,' '
.endif
.else
mov al,'d'
.endif
.endif
call print_char
inc char_position
.if op_seg_overide != NULL
mov edx,op_seg_overide
call string
mov al,':'
call print_char
.endif
.ELSEIF BL == TT_sreg3_TTT
shr al,3
call Plot_Sreg_field
.ELSEIF BL == TTT_sreg2_TTT
shr al,3
and al,3
call Plot_Sreg_field
.ELSEIF BL == port_number_IN
xor eax,eax
call Plot_reg_field
call Print_comma
mov eax,[esi]
call hex_byte
.ELSEIF BL == port_number_OUT
mov eax,[esi]
call hex_byte
mov al,','
call Print_char
xor eax,eax
call Plot_reg_field
.ELSEIF BL == port_DX_OUT
mov edx,offset EDX_symb+1
call String
mov al,','
call Print_char
xor eax,eax
call Plot_reg_field
dec esi
.ELSEIF BL == port_DX_IN
xor eax,eax
call Plot_reg_field
mov al,','
call Print_char
mov edx,offset EDX_symb+1
call String
dec esi
.ELSEIF BL == mod_zxreg_rm
shr al,3
mov bl,reg_size
mov reg_size,1
call Plot_reg_field
call Print_comma
.if bl == 1
mov force_16bitreg,1
mov edx,offset word_ptr_symb
.else
mov edx,offset byte_ptr_symb
.endif
shr al,3
.if al != 11b
call string
.endif
mov reg_size,0
call extract_mod_rm
.ELSEIF BL == mod_TTT_rm
call extract_mod_rm
.ELSEIF BL == mod_reg_rm
.if op_direc == 1
shr al,3
call Plot_reg_field
mov al,','
call print_char
call extract_mod_rm
.else
push esi
call extract_mod_rm
mov edx,esi
pop esi
mov al,','
call print_char
mov al,[esi]
shr al,3
call Plot_reg_field
mov esi,edx
.endif
.ELSEIF BL == mod_sreg3_rm
mov force_16bitreg,1
.if op_direc == 1
shr al,3
call Plot_Sreg_field
mov al,','
call print_char
call extract_mod_rm
.else
push esi
call extract_mod_rm
mov edx,esi
pop esi
mov al,','
call print_char
mov al,[esi]
shr al,3
call Plot_Sreg_field
mov esi,edx
.endif
.ELSEIF BL == TT_CR0_reg
mov edx,offset CR0_symb
call plot_special_register
.ELSEIF BL == TT_DR0_reg
mov edx,offset DR0_symb
call plot_special_register
.ELSEIF BL == TT_TR0_reg
mov edx,offset TR0_symb
call plot_special_register
.ELSEIF BL == full_displacement
mov eax,[esi]
add eax,esi
add eax,4
call hex_dword
add esi,3
.ELSEIF BL == Short_displacement
movsx eax,byte ptr [esi]
add eax,esi
inc eax
call hex_dword
.ELSEIF BL == full_offset_selector
mov ax,[esi+4]
call hex_word
mov al,':'
call print_char
mov eax,[esi]
call hex_dword
add esi,5
.ELSEIF BL == unsigned_full_offset
call Print_comma
mov op_was_done,1
call plot_seg_reg
mov al,'['
call print_char
mov eax,[esi]
.if addr_size_prefix == 1
movsx eax,ax
add MOD_RM_EffectiveAddress,eax
call hex_dword
inc esi
.else
add MOD_RM_EffectiveAddress,eax
call hex_dword
add esi,3
.endif
mov al,']'
call print_char
mov MOD_RM_flag,True
.ELSEIF BL == immediate_8bit
call Print_comma
mov op_was_done,1
mov al,[esi]
call hex_byte
.ELSEIF BL == immediate_16bit
call Print_comma
mov op_was_done,1
mov eax,[esi]
call hex_word
inc ESI
.ELSEIF BL == immediate_data
call Print_comma
mov eax,[esi]
.if op_sine == 1
movsx eax,byte ptr [esi]
.if op_size_prefix == 1
call hex_word
.else
call hex_dword
.endif
.elseif reg_size == 1
.if op_size_prefix == 1
call hex_word
add esi,1
.else
call hex_dword
add esi,3
.endif
.else
call hex_byte
.endif
call Set_OP_size_flag
.ENDIF
inc edi
inc esi
cmp byte ptr [edi],NULLL
je exit
cmp edi,format_ends
jb Operand_decode_loop
exit: movzx edi,char_position
add edi,StringBufferPTR
mov byte ptr [edi],0
clc
ret
Decode_instruction ENDP
;======================================================================
;
; PLOTS A COMMA ON IF NEEDS TO
;
;======================================================================
Print_comma PROC PRIVATE USES EAX
.if op_was_done == 1
mov al,','
call print_char
.endif
ret
Print_comma ENDP
;======================================================================
;
; PLOTS A SPECIAL CPU REGISTER ( EXPECTS edx -> REGISTER TABLE )
;
;======================================================================
plot_special_register PROC PRIVATE
.if op_direc == 1
and al,00111000B
shr al,1
movzx eax,al
add edx,eax
call String
mov al,','
call print_char
mov al,[esi]
call Plot_reg_field
.else
call Plot_reg_field
call print_comma
and al,00111000B
shr al,1
movzx eax,al
add edx,eax
call String
.endif
ret
plot_special_register ENDP
;======================================================================
;
; PLOTS A REGISTER of AL given it's "reg_size"
;
;======================================================================
Plot_reg_field PROC PRIVATE USES EDX EAX
mov op_was_done,1
and al,7
movzx edx,al
shl edx,2
.if force_16bitreg != 1
.if reg_size == 1
add edx,offset EAX_symb
.if op_size_prefix == 1
inc edx
.endif
.else
add edx,offset AL_symb
.endif
.else
add edx,offset EAX_symb+1
.endif
call string
call Set_OP_size_flag
ret
Plot_reg_field ENDP
;=======================================================================
Set_OP_size_flag PROC PRIVATE
.if force_16bitreg != 1
.if reg_size == 1
.if op_size_prefix == 1
mov MOD_RM_size,1
.endif
.else
mov MOD_RM_size,0
.endif
.else
mov MOD_RM_size,1
.endif
ret
Set_OP_size_flag ENDP
;======================================================================
;
; PLOTS A SEGMENT REGISTER of AL
;
;======================================================================
Plot_Sreg_field PROC PRIVATE USES EDX EAX
mov op_was_done,1
and al,7
movzx edx,al
shl edx,2
add edx,offset ES_symb
call string
mov MOD_RM_size,1
ret
Plot_Sreg_field ENDP
;=======================================================================
Extract_mod_rm PROC PRIVATE
.if addr_size_prefix == 1
call Extract16bit_mod_rm
.else
call Extract32bit_mod_rm
.endif
call Set_OP_size_flag
ret
Extract_mod_rm ENDP
;=======================================================================
;
; plots the data for the 32bit mod r/m
;
; Expects: esi -> instruction.
; Returns: esi -> end byte of address field.
;=======================================================================
Extract32bit_mod_rm PROC PRIVATE USES EDX EAX
LOCAL op_rm :byte
LOCAL op_mod :byte
LOCAL sib_base :byte
LOCAL sib_index :byte
LOCAL sib_scale :byte
mov op_was_done,1
mov al,[esi]
mov op_rm,al
and op_rm,7
shr al,6
mov op_mod,al
.if op_mod == 11b
mov al,op_rm
call Plot_reg_field
.elseif op_rm != 100b
mov MOD_RM_flag,True
call plot_seg_reg
mov al,'['
call Print_char
.if op_rm == 101b
.if op_mod == 00b
jmp @f
.endif
mov MOD_RM_DefaultSegmentReg,offset SS_symb
mov MOD_RM_SegmentReg,00110110b
.endif
mov al,op_rm
and al,7
movzx edx,al
shl edx,2
mov eax,registers_save.prg_eax[edx]
add MOD_RM_EffectiveAddress,eax
add edx,offset EAX_symb
call string
mov al,'+'
.if op_mod == 01b
call print_char
inc esi
movsx eax,byte ptr [esi]
add MOD_RM_EffectiveAddress,eax
call hex_dword
.elseif op_mod == 10b
call print_char
@@: mov eax,[esi+1]
add MOD_RM_EffectiveAddress,eax
call hex_dword
add esi,4
.endif
mov al,']'
call Print_char
.ELSE ;================= S-I-B ===========
mov MOD_RM_flag,True
inc esi
mov al,[esi]
mov sib_base,al
and sib_base,7
shr al,3
mov sib_index,al
and sib_index,7
shr al,3
mov sib_scale,al
call plot_seg_reg
mov al,'['
call Print_char
.if sib_base == 101b
.if op_mod == 00b
mov eax,[esi+1]
add MOD_RM_EffectiveAddress,eax
call hex_dword
add esi,4
jmp @F
.endif
mov MOD_RM_DefaultSegmentReg,offset SS_symb
mov MOD_RM_SegmentReg,00110110b
.endif
.if sib_base == 100b
mov MOD_RM_DefaultSegmentReg,offset SS_symb
mov MOD_RM_SegmentReg,00110110b
.endif
;--------- plot base -------
movzx edx,sib_base
shl edx,2
mov eax,registers_save.prg_eax[edx]
add MOD_RM_EffectiveAddress,eax
add edx,offset EAX_symb
call string
@@:
;--------- plot sacled index -------
.if sib_index != 100b
mov al,'+'
call print_char
.if sib_scale !=0
mov al,1
mov cl,sib_scale
shl al,cl
add al,'0'
call print_char
mov al,'*'
call print_char
.endif
movzx edx,sib_index
shl edx,2
mov eax,registers_save.prg_eax[edx]
mov cl,sib_scale
shl eax,cl
add MOD_RM_EffectiveAddress,eax
add edx,offset EAX_symb
call string
.endif
;--------- plot displacement -------
mov al,'+'
.if op_mod == 01b
call print_char
inc esi
movsx eax,byte ptr [esi]
add MOD_RM_EffectiveAddress,eax
call hex_dword
.elseif op_mod == 10b
call print_char
mov eax,[esi+1]
add MOD_RM_EffectiveAddress,eax
call hex_dword
add esi,4
.endif
mov al,']'
call Print_char
.endif
ret
Extract32bit_mod_rm ENDP
;=======================================================================0
;
; plots the data for the 16bit mod r/m
;
; Expects: esi -> instruction.
; Returns: esi -> end byte of address field.
;=======================================================================0
Extract16bit_mod_rm PROC PRIVATE USES EDX EAX
LOCAL op_rm :byte
LOCAL op_mod :byte
mov op_was_done,1
mov al,[esi]
mov op_rm,al
and op_rm,7
shr al,6
mov op_mod,al
.IF op_mod == 11b
;========== rm = register ===================
mov al,op_rm
call Plot_reg_field
.ELSE ;========== rm = memory ===================
mov MOD_RM_flag,True
call plot_seg_reg
mov al,'['
call Print_char
.if op_rm == 110b
.if op_mod == 00b
jmp @f
.endif
mov MOD_RM_DefaultSegmentReg,offset SS_symb
mov MOD_RM_SegmentReg,00110110b
.endif
.if op_rm == 011b
mov MOD_RM_DefaultSegmentReg,offset SS_symb
mov MOD_RM_SegmentReg,00110110b
.elseif op_rm == 010b
mov MOD_RM_DefaultSegmentReg,offset SS_symb
mov MOD_RM_SegmentReg,00110110b
.endif
mov al,op_rm
and al,7
movzx edx,al
.if al == 0
mov eax,registers_save.prg_ebx
add eax,registers_save.prg_esi
.elseif al == 1
mov eax,registers_save.prg_EBX
add eax,registers_save.prg_EDI
.elseif al == 2
mov eax,registers_save.prg_EBP
add eax,registers_save.prg_ESI
.elseif al == 3
mov eax,registers_save.prg_EBP
add eax,registers_save.prg_EDI
.elseif al == 4
mov eax,registers_save.prg_ESI
.elseif al == 5
mov eax,registers_save.prg_EDI
.elseif al == 6
mov eax,registers_save.prg_EBP
.elseif al == 7
mov eax,registers_save.prg_EBX
.endif
movsx eax,ax
add MOD_RM_EffectiveAddress,eax
shl edx,3
add edx,offset mod_rm_16bit
call string
mov al,'+'
.if op_mod == 01b
call print_char
inc esi
movsx eax,byte ptr [esi]
add MOD_RM_EffectiveAddress,eax
call hex_word
.elseif op_mod == 10b
call print_char
@@: movsx eax,word ptr [esi+1]
add MOD_RM_EffectiveAddress,eax
call hex_word
add esi,2
.endif
mov al,']'
call Print_char
.endif
ret
Extract16bit_mod_rm ENDP
hex_dword PROC PRIVATE USES ECX EAX
mov cl,8
call hex_print
ret
hex_dword ENDP
hex_byte PROC PRIVATE USES ECX EAX
rol eax,24
mov cl,2
call hex_print
ret
hex_byte ENDP
hex_word PROC PRIVATE USES ECX EAX
rol eax,16
mov cl,4
call hex_print
ret
hex_word ENDP
hex_print PROC PRIVATE USES EDX
mov edx,eax
he_plotloop:
rol edx,4
movzx eax,dl
and al,0fh
mov al,HexChars[eax]
call print_char
dec cl
jnz he_plotloop
ret
HexChars db '0123456789abcdef'
hex_print ENDP
String PROC PRIVATE USES EAX
strloop: mov al,[edx]
cmp al,'$'
je exit
call Print_char
inc edx
jmp strloop
exit: ret
String ENDP
Print_char PROC PRIVATE USES EDX
movzx edx,char_position
add edx,StringBufferPTR
mov [edx],al
inc char_position
ret
Print_char ENDP
;=========================================================================
plot_seg_reg PROC PRIVATE
.if op_seg_overide != NULL
mov edx,op_seg_overide
call String
mov al,':'
call Print_char
.endif
ret
plot_seg_reg ENDP