\\ *** Disassembler for the i486 *** 08nov92py \ i486 disassembler loadscreen 19may97py Module Disass base @ $8 base ! Variable cp? 1 ?head ! \ alle Disassembler-Worte headerless 1 capacity 2- +thru export dis disw disline .86 .386 ; base ! Module; \ long words and presigns 31dec92py : .# '# emit ; : .$ '$ emit ; : ., ', emit ; : .+ '+ emit ; : .- '- emit ; : .. '. emit ; : .: ': emit ; : .[ '[ emit ; : .] '] emit ; : cr? col IF cr THEN ; \ signed / unsigned byte, word and long output 07aug10py : .lformat ( addr -- ) $8 u.r ." :" ; : .du ( n -- ) 0 <<# #s #> type #>> ; : .$du ( n -- ) .$ .du ; : .$ds ( n -- ) dup 0< IF .- negate THEN .$du ; : .by ( 8b -- ) 0 <<# # # #> type #>> ; : .$bu ( 8b -- ) .$ .by ; : .$bs ( 8b -- ) $FF and dup $7F > IF .- $100 swap - THEN .$bu ; : .dump ( addr len -- ) bounds DO i c@ .by LOOP ; \ Variables and tabs 16nov97py Variable opcode Variable mode Variable length Variable alength Variable .length Variable .alength Variable seg: seg: on &36 constant bytfld : tab row swap at ; &10 constant mnefld &18 constant addrfld : tab1 addrfld col - 1 max spaces ; : l! .length @ length ! .alength @ alength ! seg: on ; : t, swap c, c, ' A, '" parse here $A allot place ; \ Strings 07feb93pyCreate "regs ," AXCXDXBXSPBPSIDIALCLDLBLAHCHDHBH" Create "16ri ," BX+SIBX+DIBP+SIBP+DISI DI BP BX " Create "ptrs ," DWORDWORD BYTE " Create "idx ," *2*4*8" Create "seg ," ESCSSSDSFSGS" Create "seg1 ," escsssdsfsgs" Create "jmp ," o b z bes p l le" Create grp1 ," addor adcsbbandsubxorcmprolrorrclrcrshlshrsalsar"Create grp3 ," testtestnot neg mul imuldiv idiv" Create grp4 ," inc dec call callfjmp jmpf push g4?? " Create grp6 ," sldtstr lldtltr verrverwg6??g6??sgdtsidtlgdtlidtsmswg7??lmswg7??" Create grp8 ," ???? src" 2 "regs c! 5 "16ri c! 5 "ptrs c! 2 "idx c! 2 "seg c! 2 "seg1 c! 2 "jmp c! 3 grp1 c! 4 grp3 c! 5 grp4 c! 4 grp6 c! 1 grp8 c! \ Register display 05dec92py : *." ( n addr -- ) count >r swap r@ * + r> -trailing type ; : .(reg ( n l -- ) dup 0= IF drop 'E emit ELSE 2 = IF 8+ THEN THEN "regs *." ; : .reg ( n -- ) length @ .(reg ; : .ereg ( n -- ) 'E emit "regs *." ; : .seg ( n -- ) "seg *." ; : mod@ ( addr -- addr' r/m reg ) count dup 70 and 3 >> swap 307 and swap ; : .8b ( addr -- addr' ) count .$bs ; : .32b ( addr -- addr' ) dup @ .$ds 4+ ; : .32u ( addr -- addr' ) dup @ .$du 4+ ; \ Register display 05dec92py Table: .disp noop .8b .32b [ : .sib ( addr mod -- addr' ) >r count dup 7 and 5 = r@ 0= and IF rdrop >r .32b r> ELSE swap r> cells .disp + perform swap dup 7 and .[ .ereg .] THEN 3 >> dup 7 and 4 = 0= IF .[ dup 7 and .ereg 3 >> "idx *." .] ELSE drop THEN ; : .32a ( addr r/m -- addr' ) dup 7 and >r 6 >> dup 3 = IF drop r> .reg exit THEN dup 0= r@ 5 = and IF drop rdrop .[ .32u .] exit THEN r@ 4 = IF rdrop .sib exit THEN cells .disp + perform r> .[ .ereg .] ; \ Register display 29may10py : wcount ( addr -- addr' w ) w@+ swap ; : wxcount ( addr -- addr' w ) wx@+ swap ; : +8b ( addr -- addr' ) count .$bs ; : +16b ( addr -- addr' ) wcount .$ds ; Table: .16disp noop +8b +16b [ : .16r ( reg -- ) .[ "16ri *." .] ; : .16a ( addr r/m -- addr' ) 307 and dup 006 = IF drop wcount .[ .$du .] exit THEN dup 7 and >r 6 >> dup 3 = IF drop r> .reg exit THEN cells .16disp + perform r> .16r ; \ Register display 01jan93py : .addr ( addr r/m -- addr' ) seg: @ 0< 0= IF seg: @ .seg ': emit THEN alength @ IF .16a ELSE .32a THEN ; : .ptr ( addr r/m -- addr' ) dup 300 < IF length @ "ptrs *." ." PTR " THEN .addr ; : .mod ( addr -- addr' ) mod@ .reg ., .addr ; : .rmod ( addr -- addr' ) mod@ >r .addr r> ., .reg ; : .imm ( addr -- addr' ) length @ dup 0= IF drop dup @ .$ds 4+ exit THEN 1 = IF wcount .$ds exit THEN count .$bs ; \ .ari 07feb93py forward .code : .b? ( -- ) opcode @ 1 and 0= IF 2 length ! THEN ; : .ari .b? tab1 opcode @ dup 4 and IF drop 0 .reg ., .imm exit THEN 2 and IF .mod ELSE .rmod THEN ; : .modt tab1 .mod ; : .gr tab1 opcode @ 7 and .reg ; : .igrv .gr ., .imm ; : .igrb 2 length ! .igrv ; : .igr .b? .igrv ; : .modb .b? tab1 .rmod ; : .xcha .gr ., 0 .reg ; \ .conds modifier 29may10py : .cond ( -- ) opcode @ 17 and dup 1 and IF Ascii n emit THEN 2/ "jmp *." ; : .jb tab1 count dup $80 and IF -$80 or THEN over + .$du ; : .jv tab1 alength @ IF wxcount over ELSE dup @ swap 4+ under THEN + .$du ; : .js .cond .jb ; : .jl .cond .jv ; : .set .cond tab1 mod@ drop 2 length ! .ptr ; : asize alength @ invert alength ! .code ; : osize length @ 1 xor length ! .code ; : .seg: opcode @ 3 >> 3 and seg: ! .code ; : .segx opcode @ 1 and 4+ seg: ! .code ; : .pseg tab1 opcode @ 3 >> 7 and .seg ; \ .grp1 .grp4 .adj .arpl 05dec92py: .grp1 .b? mod@ grp1 *." tab1 .ptr ., opcode @ 3 and 3 = IF 2 length ! THEN .imm ; : .grp2 .b? mod@ 8+ grp1 *." tab1 .ptr ., opcode @ 2 and IF ." CL" ELSE ." 1" THEN ; : .grp3 .b? mod@ dup >r grp3 *." tab1 r@ 3 > IF 0 .reg ., THEN r@ 2 4 within IF .ptr ELSE .addr THEN r> 2 < IF ., .imm THEN ; : .grp4 .b? mod@ dup grp4 *." tab1 2+ 7 and 4 < IF .ptr ELSE .addr THEN ; : .adj opcode @ dup $10 and IF Ascii a ELSE Ascii d THEN emit Ascii a emit $8 and IF Ascii s ELSE Ascii a THEN emit ; : .seg# .[ dup alength @ 2* 4+ + wcount .$du .: swap alength @ IF wcount .$du ELSE .32u THEN .] drop ; \ .movo .movx .str 23jan93py: .movo tab1 .b? opcode @ 2 and 0= IF 0 .reg ., THEN $05 alength @ - .addr opcode @ 2 and IF ., 0 .reg THEN ; : .movx tab1 mod@ .reg ., 1 length ! .b? .ptr ; : .movi .b? tab1 mod@ drop .ptr ., .imm ; : .movs tab1 mod@ opcode @ 2 and IF .seg ., .addr ELSE >r .addr ., r> .seg THEN ; : .str .b? " dwb" 1+ length @ + c@ emit ; : .far tab1 .seg# ; : .modiv .modt ., .imm ; : .modib .modt ., 2 length ! .imm ; : .iv tab1 .imm ; : .ib 2 length ! .iv ; : .ev tab1 mod@ drop .ptr ; : .arpl tab1 1 length ! .rmod ; \ .mne 16nov97py : .io tab1 .b? 0 .reg ., 1 length ! 2 .reg ; : .io# tab1 .b? 0 .reg ., count .$bu ; : .ret opcode @ 1 and 0= IF tab1 wcount .$du THEN ; : .enter tab1 wcount .$du ., count .$bu ; : .stcl opcode @ 1 and IF ." st" ELSE ." cl" THEN " cid " 1+ opcode @ 2/ 3 and + c@ emit ; : .mne ( addr field -- addr' ) >r count dup opcode ! r> BEGIN 2dup c@ and over 1+ c@ = 0= WHILE $10 + REPEAT nip dup 6+ count type 2+ perform l! ; forward mntbl : .code mntbl .mne ; \ .grp6 .grp7 07aug10py : .grp6 1 length ! mod@ opcode @ 4* 2* + grp6 *." tab1 .addr ; : .grp2i .b? mod@ 8+ grp1 *." tab1 .ptr ., 2 length ! .imm ; : .grp8 mod@ grp8 *." tab1 .addr ., 2 length ! .imm ; : .bt opcode @ 3 >> 7 and grp8 *." tab1 .rmod ; Create lbswap 0 c, 3 c, 3 c, 0 c, : .movrx tab1 opcode @ dup 3 and lbswap + c@ xor 7 and >r mod@ r@ 1 and IF swap 7 and .reg ., THEN r@ 2/ " CDT?" + 1+ c@ swap 0 <<# # 'R hold rot hold #> type #>> r> 1 and 0= IF ., 7 and .reg THEN ; : .lxs opcode @ 7 and "seg1 *." .modt ; : .shd tab1 .rmod ., 2 length ! opcode @ 1 and IF 1 .reg ELSE .imm THEN ; \ .esc 22may93py: flt, c, bl parse here over 1+ allot place ; Create fop1table hex 80 flt, chs 81 flt, abs 84 flt, tst 85 flt, xam 08 flt, ld1 09 flt, ldl2t 0A flt, ldl2e 0B flt, ldpi 0C flt, ldlg2 0D flt, ldln2 0E flt, ldz 90 flt, 2xm1 D1 flt, yl2x 92 flt, ptan D3 flt, patan 94 flt, xtract D5 flt, prem1 16 flt, decstp 17 flt, incstp D8 flt, prem D9 flt, yl2xp1 9A flt, sqrt 9B flt, sincos 9C flt, rndint DD flt, scale 9E flt, sin 9F flt, cos : .st ." ST" ?dup IF ." (" 1 .r ." )" THEN ; : .st? dup 40 and IF 1 .st ., THEN 80 and IF 0 .st THEN ; : .fop1 ( IP opcode -- IP ) 1F and >r fop1table BEGIN count 1F and r@ < WHILE count + REPEAT dup 1- c@ dup 1F and r> = IF swap count type tab1 .st? ELSE ." ??" 2drop THEN ; \ .esc 18dec93pyCreate fopbtable 00 flt, add 01 flt, mul 02 flt, com 03 flt, comp 04 flt, sub 05 flt, subr 06 flt, div 07 flt, divr 08 flt, ld 09 flt, xch 0A flt, st 0B flt, stp Create "fptrs ," SFLOATDWORD DFLOATWORD " 6 "fptrs c! : .modst count type dup 200 and IF ." p" THEN tab1 dup 400 and IF dup 7 and .st ., THEN 0 .st dup 400 and 0= IF dup 7 and ., .st THEN drop ; : .fmodm over 9 >> dup >r 1 and IF ." i" THEN count type tab1 r> "fptrs *." ." PTR " FF and .addr ; : .modfb ( IP opcode -- IP' ) 1D0 case? IF ." nop" exit THEN dup 7F8 and 5C0 = IF ." free" tab1 7 and .st exit THEN dup dup 38 and 3 >> swap 100 and 5 >> or >r fopbtable BEGIN count 1F and r@ < WHILE count + REPEAT rdrop over C0 and C0 = IF .modst ELSE .fmodm THEN ; \ .esc 22may93pyCreate fopatable 00 flt, ldenv 01 flt, ldcw 02 flt, stenv 03 flt, stcw 05 flt, ld 07 flt, stp 08 flt, rstor 0A flt, save 0B flt, stsw 0C flt, bld 0D flt, ild 0E flt, bstp 0F flt, istp : .modfa ( IP opcode -- IP' ) 7E0 case? IF ." stsw" tab1 ." AX" exit THEN dup 600 and 7 >> over 18 and 3 >> or >r fopatable BEGIN count 1F and r@ < WHILE count + REPEAT dup 1- c@ r> = 0= IF drop " ??" THEN count type tab1 FF and .addr ; \ .esc 02mar97py : .fop2 1F and 2 case? IF ." clex" exit THEN 3 case? IF ." init" exit THEN ." ??" . ; : .esc ( ip -- ip' ) count opcode @ 7 and 8 << or dup 7E0 and 1E0 = IF .fop1 exit THEN dup 7E0 and 3E0 = IF .fop2 exit THEN dup 120 and 120 = IF .modfa exit THEN .modfb ; \ .mmi 02mar97py : .mmr ( reg -- ) ." MM" 7 and 0 .r ; : .mma ( r/m -- ) dup $C0 < IF ." QUAD PTR " .addr ELSE .mmr THEN ; : .mmq ( ip -- ip' ) tab1 mod@ .mmr ., .mma ; : .mms ( -- ) opcode @ 3 and s" bwdq" drop + c@ emit ; : .mmx ( ip -- ip' ) .mms .mmq ; : .mmi ( ip -- ip' ) mod@ 2/ 3 and s" ??rlrall" drop swap 2* + 2 type .mms tab1 .mmr ., .8b ; \ 0Ffld 16nov97pyCreate 0Ftbl FE 00 t, .grp6 " FF 02 t, .modt lar" FF 03 t, .modt lsl" FF 06 t, noop clts" F8 20 t, .movrx mov" FF 08 t, noop invd" FF 09 t, noop wbinvd" F0 80 t, .jl j" F0 90 t, .set set" F7 A0 t, .pseg push" F7 A1 t, .pseg pop" FE A4 t, .shd shld" FE AC t, .shd shrd" E7 A3 t, .bt bt" FE A6 t, .modb cmpxchg" FE B6 t, .movx movzx" FF BA t, .grp8 bt" F8 B0 t, .lxs l" FE BE t, .movx movsx" FE C0 t, .modb xadd" F8 C8 t, .gr bswap" FF AF t, .modt imul" FF BC t, .modt bsf" FF BD t, .modt bsr" FF C7 t, .ev cmpxchg8b" \ 0Ffld 12apr98py FC 70 t, .mmi ps" FF 30 t, noop wrmsr" FF 32 t, noop rdmsr" FF D5 t, .mmq pmullw" FF E5 t, .mmq pmulhw" FF F5 t, .mmq pmaddwd" FF DB t, .mmq pand" FF $DF t, .mmq pandn" FF EB t, .mmq por" FF EF t, .mmq pxor" FC D0 t, .mmx psrl" FC D8 t, .mmx psubu" FC E0 t, .mmx psra" FC E8 t, .mmx psubs" FC F0 t, .mmx psll" FC F8 t, .mmx psub" FC DC t, .mmx paddu" FC EC t, .mmx padds" FC FC t, .mmx padd" 00 00 t, noop 0F???" : .0f 0Ftbl .mne ; \ disassembler table 22may93pyCreate mntbl FF 0F t, .0f " E7 06 t, .pseg push" E7 07 t, .pseg pop" F8 00 t, .ari add" F8 08 t, .ari or" F8 10 t, .ari adc" F8 18 t, .ari sbb" E7 26 t, .seg: " E7 27 t, .adj " F8 20 t, .ari and" F8 28 t, .ari sub" F8 30 t, .ari xor" F8 38 t, .ari cmp" F8 40 t, .gr inc" F8 48 t, .gr dec" F8 50 t, .gr push" F8 58 t, .gr pop" FF 60 t, noop pusha" FF 61 t, noop popa" FF 62 t, .modt bound" FF 63 t, .arpl arpl" FE 64 t, .segx " FF 66 t, osize " FF 67 t, asize " \ disassembler table 21may94py FF 68 t, .iv push" FF 69 t, .modiv imul" FF 6A t, .ib push" FF 6B t, .modib imul" FE 6C t, .str ins" FE 6E t, .str outs" F0 70 t, .js j" FF 82 t, noop ???" FC 80 t, .grp1 " FE 84 t, .modb test" FE 86 t, .modb xchg" FC 88 t, .ari mov" FD 8C t, .movs mov" FF 8D t, .modt lea" FF 8F t, .ev pop" FF 90 t, noop nop" F8 90 t, .xcha xchg" FF 98 t, noop cbw" FF 99 t, noop cwd" FF 9A t, .far callf" FF 9B t, noop wait" FF 9C t, noop pushf" FF 9D t, noop popf" FF 9E t, noop sahf" FF 9F t, noop lahf" \ disassembler table 22may93py FC A0 t, .movo mov" FE A4 t, .str movs" FE A6 t, .str cmps" FE A8 t, .igr test" FE AA t, .str stos" FE AC t, .str lods" FE AE t, .str scas" F8 B0 t, .igrb mov" F8 B8 t, .igrv mov" FE C0 t, .grp2i " FE C2 t, .ret ret" FF C4 t, .modt les" FF C5 t, .modt lds" FE C6 t, .movi mov" FF C8 t, .enter enter" FF C9 t, noop leave" FE CA t, .ret retf" FF CC t, noop int3" FF 0CD t, .ib int" FF CE t, noop into" FF CF t, noop iret" \ disassembler table 12aug00pyFC D0 t, .grp2 " FF D4 t, noop aam" FF D5 t, noop aad" FF D6 t, noop salc" FF D7 t, noop xlat" F8 D8 t, .esc f" FF E0 t, .jb loopne" FF E1 t, .jb loope" FF E2 t, .jb loop" FF E3 t, .jb jcxz" FE E4 t, .io# in" FE E6 t, .io# out" FF E8 t, .jv call" FF E9 t, .jv jmp" FF EA t, .far jmpf" FF EB t, .jb jmp" FE EC t, .io in" FE EE t, .io out" FF F0 t, .code lock " FF F2 t, .code rep " FF F3 t, .code repe " FF F4 t, noop hlt" FF F5 t, noop cmc" FE F6 t, .grp3 " FE FE t, .grp4 " F8 F8 t, .stcl " 00 00 t, noop ???" \ addr! dis disw disline 13may95py: disline base push hex dup .lformat mnefld tab dup .code col bytfld < 0= IF cr THEN bytfld tab swap 2dup - .dump ; ?head off : dis &20 BEGIN cr? more? dup 0< 0= WHILE >r disline r> REPEAT cr? 2drop ; : disw ' dup ." Adresse : " u. cr? &20 BEGIN BEGIN cr? more? dup 0< 0= WHILE >r disline r> opcode @ $C3 = UNTIL THEN drop &20 key $FF and #esc = UNTIL cr? 2drop ; : disline ( addr -- addr' ) base push hex .code at? &48 max at ; : .86 1 .length ! .alength on l! ; : .386 .length off .alength off l! ;