home *** CD-ROM | disk | FTP | other *** search
/ Liren Large Software Subsidy 10 / 10.iso / l / l440 / 2.ddi / CHAP7 / DIS.ASM < prev    next >
Encoding:
Assembly Source File  |  1990-08-25  |  16.4 KB  |  998 lines

  1.     page    78,132
  2.     title    Disassembly command
  3.  
  4. ActionBits    =    4
  5. ActionMask    =    (1 shl ActionBits) - 1
  6. SubIndexMask    =    not ActionMask
  7.  
  8.     .sall
  9. dm        MACRO    string
  10. $StrSize    sizestr    <&string>
  11. $FirstStr    substr    <&string>,1,$StrSize-1
  12. $LastChar    substr    <&string>,$StrSize
  13. %        db    "&$FirstStr","&$LastChar"+80H
  14.         ENDM
  15.  
  16. DefAction    MACRO    ActName
  17. ActName&Ind    =    ($ - Actions)/2
  18.         dw    ActName
  19.         ENDM
  20.  
  21. NewAction    MACRO    ActName
  22. CurActInd    =    ActName&Ind
  23. ActName&Ops    label    word
  24. pos        =    0
  25.         ENDM
  26.     
  27. DefMne        MACRO    mnemonic
  28. Strings        segment
  29. mnemonic&Op    label    byte
  30.         dm    mnemonic
  31. Strings        ends
  32.         .code
  33.         dw    offset DGroup:mnemonic&Op
  34.         ENDM
  35.  
  36. OpInd    MACRO    opcode,MneInd
  37. CurPos    =    $
  38. .erre    CurActInd LE ActionMask
  39.     org    OpGroup+opcode
  40.     db    CurActInd + MneInd * (ActionMask+1)
  41.     org    CurPos
  42.     ENDM
  43.  
  44. DefOp    MACRO    opcode,mnemonic,count
  45.     IFB    <count>
  46. cnt    =    1
  47.     ELSE
  48. cnt    =    count
  49.     ENDIF
  50.     IRP    opc,<opcode>
  51. i    =    0
  52.     REPT    cnt
  53.     OpInd    opc+i,pos
  54. i    =    i+1
  55.     ENDM    ;;REPT
  56.     ENDM    ;;IRP
  57.     IFNB    <mnemonic>
  58. char1    substr    <mnemonic>,1,1
  59. %    IFIDN    <char1>,<_>
  60. Lchar    substr    <mnemonic>,2
  61. OpNam    catstr    Lchar,<Op>
  62.     dw    offset DGroup:OpNam
  63.     ELSE
  64.     DefMne    mnemonic
  65.     ENDIF    ;;IFIDN
  66.     ENDIF    ;;IFNB mnemonic
  67. pos    =    pos + 1
  68.     ENDM
  69.  
  70. DefSpc    MACRO    opcode,action,count
  71.     IFB    <count>
  72. cnt    =    1
  73.     ELSE
  74. cnt    =    count
  75.     ENDIF
  76.     IRP    opc,<opcode>
  77. i    =    0
  78.     REPT    cnt
  79.     OpInd    opc+i,pos
  80. i    =    i+1
  81.     ENDM    ;;REPT
  82.     ENDM    ;;IRP
  83.     dw    offset DGroup:action
  84. pos    =    pos + 1
  85.     ENDM
  86.  
  87.     .model    small
  88.     .code
  89.     .data
  90. Strings    segment    byte public
  91. Strings    ends
  92.  
  93. DGroup    group    _DATA,Strings
  94.  
  95.     .data
  96.  
  97.     extrn    BxSave:word, BpSave:word, SiSave:word, DiSave:word, CsSave:word
  98.  
  99. fAddr32        =    1
  100. fData32        =    2
  101. FlagWord    dw    0
  102. Prefix        equ    byte ptr FlagWord
  103. Override    equ    byte ptr FlagWord+1
  104. DisBuf        db    80 dup(?)
  105. DefDis        dw    0,0
  106.  
  107.     .code
  108.  
  109.     public    UnAssemble,DisLine
  110.  
  111.     extrn    Default:near, PrintMes:near, OutCh:near, OutSi:near
  112.  
  113. tByteReg    label    word    
  114.     db    "al"
  115.     db    "cl"
  116.     db    "dl"
  117.     db    "bl"
  118.     db    "ah"
  119.     db    "ch"
  120.     db    "dh"
  121.     db    "bh"
  122.  
  123. tWordReg    label    word
  124.     db    "ax"
  125.     db    "cx"
  126.     db    "dx"
  127.     db    "bx"
  128.     db    "sp"
  129.     db    "bp"
  130.     db    "si"
  131.     db    "di"
  132.  
  133. tSegReg        label    word
  134.     db    "es"
  135.     db    "cs"
  136.     db    "ss"
  137.     db    "ds"
  138.     db    "fs"
  139.     db    "gs"
  140.  
  141. tShiftOps    label    word
  142.     DefMne    rol
  143.     DefMne    ror
  144.     DefMne    rcl
  145.     DefMne    rcr
  146.     DefMne    shl
  147.     DefMne    shr
  148.     DefMne    sal
  149.     DefMne    sar
  150.  
  151. tGrp3Ops    label    word
  152.     dw    offset DGroup:TestOp
  153.     dw    offset DGroup:TestOp
  154.     DefMne    not
  155.     DefMne    neg
  156.     DefMne    mul
  157.     DefMne    imul
  158.     DefMne    div
  159.     DefMne    idiv
  160.  
  161. tGrp4Ops    label    word
  162.     dw    offset DGroup:IncOp
  163.     dw    offset DGroup:DecOp
  164.     dw    offset DGroup:CallOp
  165.     dw    offset DGroup:CallOp
  166.     dw    offset DGroup:JmpOp
  167.     dw    offset DGroup:JmpOp
  168.     dw    offset DGroup:PushOp
  169.     dw    offset DGroup:???Op
  170.  
  171.  
  172. XlatOp:        dm    xlat
  173. IntOp:        dm    int
  174. EscOp:        dm    esc
  175. ByteMsg:    dm    byte
  176. WordMsg:    dm    word
  177. DwordMsg:    dm    dword
  178. PtrMsg:        dm    < ptr >
  179.  
  180. AddrBx    =    1
  181. AddrBp    =    2
  182. AddrSi    =    4
  183. AddrDi    =    8
  184. AddrPlus=    10H
  185.  
  186. AddrMod16    label    byte
  187.     db    AddrBx+AddrSi+AddrPlus
  188.     db    AddrBx+AddrDi+AddrPlus
  189.     db    AddrBp+AddrSi+AddrPlus
  190.     db    AddrBp+AddrDi+AddrPlus
  191.     db    AddrSi
  192.     db    AddrDi
  193.     db    AddrBp
  194.     db    AddrBx
  195.  
  196. OpGroup    db    100H dup(0)        ;Allocate opcode lookup table
  197.  
  198. Actions    label    word
  199.     DefAction    OneByte
  200.     DefAction    OneByte2
  201.     DefAction    Arith
  202.     DefAction    OneReg
  203.     DefAction    CondJump
  204.     DefAction    CondJump2
  205.     DefAction    SegPush
  206.     DefAction    String
  207.     DefAction    ArithIm
  208.     DefAction    Jump
  209.     DefAction    Special
  210.     DefAction    RepLock
  211.     DefAction    InOut
  212.     DefAction    AamAad
  213.     DefAction    LdPointer
  214.     DefAction    RetImm
  215.  
  216. NewAction    OneByte            ;Start data for action routine
  217.     DefOp    0F1H,???        ;Must be first!!
  218.     DefOp    027H,daa
  219.     DefOp    02FH,das
  220.     DefOp    037H,aaa
  221.     DefOp    03FH,aas
  222.     DefOp    060H,pusha
  223.     DefOp    061H,popa
  224.     DefOp    090H,nop
  225.     DefOp    098H,cbw
  226.     DefOp    099H,cwd
  227.     DefOp    09BH,wait
  228.     DefOp    09CH,pushf
  229.     DefOp    09DH,popf
  230.     DefOp    09EH,sahf
  231.     DefOp    09FH,lahf
  232.     DefOp    0C3H,ret
  233. NewAction    OneByte2
  234.     DefOp    0C9H,leave
  235.     DefOp    0CBH,retf
  236.     DefOp    0CEH,into
  237.     DefOp    0CFH,iret
  238.     DefOp    0F4H,hlt
  239.     DefOp    0F5H,cmc
  240.     DefOp    0F8H,clc
  241.     DefOp    0F9H,stc
  242.     DefOp    0FAH,cli
  243.     DefOp    0FBH,sti
  244.     DefOp    0FCH,cld
  245.     DefOp    0FDH,std
  246. NewAction    Arith
  247. ;WARNING! this order is needed for ArithIm and Group1 decoding!
  248.     DefOp    00H,add,4
  249.     DefOp    08H,or,4
  250.     DefOp    10H,adc,4
  251.     DefOp    18H,sbb,4
  252.     DefOp    20H,and,4
  253.     DefOp    28H,sub,4
  254.     DefOp    30H,xor,4
  255.     DefOp    38H,cmp,4
  256.     DefOp    84H,test,2
  257.     DefOp    86H,xchg,2
  258.     DefOp    88H,mov,4
  259. NewAction    OneReg
  260.     DefOp    40H,inc,8
  261.     DefOp    48H,dec,8
  262.     DefOp    50H,push,8
  263.     DefOp    58H,pop,8
  264. NewAction    CondJump
  265.     DefOp    70H,jo
  266.     DefOp    71H,jno
  267.     DefOp    72H,jc
  268.     DefOp    73H,jnc
  269.     DefOp    74H,jz
  270.     DefOp    75H,jnz
  271.     DefOp    76H,jbe
  272.     DefOp    77H,ja
  273.     DefOp    78H,js
  274.     DefOp    79H,jns
  275.     DefOp    7AH,jpe
  276.     DefOp    7BH,jpo
  277.     DefOp    7CH,jl
  278.     DefOp    7DH,jge
  279.     DefOp    7EH,jle
  280.     DefOp    7FH,jg
  281. NewAction    CondJump2
  282.     DefOp    0E0H,loopne
  283.     DefOp    0E1H,loope
  284.     DefOp    0E2H,loop
  285.     DefOp    0E3H,jcxz
  286.     DefOp    0EBH,jmp
  287. NewAction    SegPush
  288.     DefOp    <06H,0EH,16H,1EH>,_push
  289.     DefOp    <07H,17H,1FH>,_pop
  290. NewAction    String
  291.     DefOp    06CH,ins,2
  292.     DefOp    06EH,outs,2
  293.     DefOp    0A4H,movs,2
  294.     DefOp    0A6H,cmps,2
  295.     DefOp    0AAH,stos,2
  296.     DefOp    0ACH,lods,2
  297.     DefOp    0AEH,scas,2
  298. NewAction    ArithIm
  299.     DefOp    04H,,2
  300.     DefOp    0CH,,2
  301.     DefOp    14H,,2
  302.     DefOp    1CH,,2
  303.     DefOp    24H,,2
  304.     DefOp    2CH,,2
  305.     DefOp    34H,,2
  306.     DefOp    3CH,,2
  307.     DefOp    0A8H,,2
  308. NewAction    Jump
  309.     DefOp    <9AH,0E8H>,call
  310.     DefOp    <0E9H,0EAH>,_jmp
  311. NewAction    Special
  312.     DefSpc    0B0H,MoveIm,16
  313.     DefSpc    91H,XchgAx,7
  314.     DefSpc    <26H,2EH,36H,3EH,64H,65H>,SegOver
  315.     DefSpc    0D7H,XlatInst
  316.     DefSpc    0A0H,MovAcc,4
  317.     DefSpc    0C6H,MovImMem,2
  318.     DefSpc    <8CH,8EH>,SegMov
  319.     DefSpc    8FH,PopMem
  320.     DefSpc    0CCH,Interrupt,2
  321.     DefSpc    0D8H,Coprocessor,8
  322.     DefSpc    80H,Group1,4
  323.     DefSpc    0C0H,Group2,2
  324.     DefSpc    0D0H,Group2,4
  325.     DefSpc    0F6H,Group3,2
  326.     DefSpc    0FEH,Group4,2
  327. NewAction    RepLock
  328.     DefOp    0F0H,lock
  329.     DefOp    0F2H,repne
  330.     DefOp    0F3H,repe
  331. NewAction    InOut
  332.     DefOp    <0E4H,0ECH>,in,2
  333.     DefOp    <0E6H,0EEH>,out,2
  334. NewAction    AamAad
  335.     DefOp    0D4H,aam
  336.     DefOp    0D5H,aad
  337. NewAction    LdPointer
  338.     DefOp    62H,bound
  339.     DefOp    8DH,lea
  340.     DefOp    0C4H,les
  341.     DefOp    0C5H,lds
  342. NewAction    RetImm
  343.     DefOp    0C2H,_ret
  344.     DefOp    0CAH,_retf
  345.  
  346.     assume    ds:nothing,es:nothing,ss:DGroup
  347.  
  348. UnAssemble:
  349.     mov    bp,[CsSave]        ;Default segment is cs
  350.     mov    cx,8
  351.     mov    di,offset DGroup:DefDis
  352.     call    Default            ;Get range to disassemble
  353.     mov    ds,ax            ;Set segment
  354.     mov    si,dx            ;SI has displacement in segment
  355. LineDis:
  356.     push    cx
  357.     call    DisLine
  358.     pop    cx
  359.     loop    LineDis
  360.     ret
  361.  
  362. DisLine:
  363. ;Display disassembly of line at ds:si
  364.     call    OutSi
  365.     mov    al,9            ;Tab char
  366.     call    OutCh
  367.     mov    di,offset DGroup:DisBuf
  368.     call    DisAssemble
  369.     mov    ax,13+(10+80H)*100H    ;Add Cr/Lf terminator
  370.     stosw
  371.     mov    word ptr [DefDis],si
  372.     mov    word ptr [DefDis+2],ds    ;Remember last addrss as default
  373.     push    ds
  374.     push    si
  375.     push    cs
  376.     pop    ds
  377.     mov    si,offset DGroup:DisBuf
  378.     call    PrintMes
  379.     pop    si
  380.     pop    ds
  381.     ret
  382.  
  383. DisAssemble:
  384. ;ds:si points to code
  385. ;es:di points to destination buffer
  386.     mov    [FlagWord],0
  387. DisNext:
  388.     lodsb                ;Get first code byte
  389.     mov    ah,al            ;Save a copy
  390.     mov    bx,offset DGroup:OpGroup
  391.     xlat    OpGroup
  392.     mov    bl,al
  393.     and    bx,ActionMask        ;Low 4 bits have action index
  394.     shl    bx,1
  395.     mov    dx,[bx].Actions        ;Get address of action routine
  396.     mov    bl,al
  397.     and    bl,SubIndexMask        ;Mask to mnemonic index
  398.     mov    cl,ActionBits - 1
  399.     shr    bx,cl            ;Now a word index
  400.     jmp    dx
  401.  
  402. Special:    
  403. ;Dispatch for those opcodes with only one mnemonic per action
  404.     jmp    [bx].SpecialOps
  405.  
  406. RepLock:
  407.     mov    bx,[bx].RepLockOps
  408.     call    CopyMsgTab
  409.     jmp    DisNext
  410.  
  411. SegOver:
  412.     mov    al,ah
  413.     cmp    al,60H            ;FS/GS?
  414.     jae    SegInPlace
  415.     mov    cl,3
  416.     shr    al,cl            ;Bring seg no. down to low end
  417.     and    al,3
  418. SegInPlace:
  419.     and    al,7
  420.     inc    ax
  421.     mov    [Override],al
  422.     jmp    DisNext
  423.  
  424. SegMov:
  425.     mov    bx,offset DGroup:MovOp
  426.     call    CopyMsgTab
  427.     lodsb                ;Get R/M byte
  428.     mov    bl,al
  429.     and    bx,7*8            ;Mask to segment reg
  430.     shr    bx,1
  431.     shr    bx,1
  432.     mov    bx,[bx].tSegReg
  433.     test    ah,2            ;To segment reg?
  434.     mov    ah,1            ;Ensure word size
  435.     jnz    ToSeg
  436.     push    bx            ;Save segment reg
  437.     call    ModRm
  438.     mov    al,","
  439.     stosb
  440.     pop    ax            ;Get seg reg back
  441.     stosw
  442.     ret
  443.  
  444. ToSeg:
  445.     xchg    bx,ax            ;Seg reg to ax
  446.     stosw
  447.     mov    al,","
  448.     stosb
  449.     xchg    bx,ax            ;Restore R/M byte
  450.     jmp    ModRm
  451.  
  452. PopMem:
  453.     mov    bx,offset DGroup:PopOp
  454.     call    CopyMsgTab
  455.     lodsb                ;Get R/M byte
  456.     jmp    ModRm
  457.  
  458. MoveIm:
  459.     mov    bx,offset DGroup:MovOp
  460.     call    CopyMsgTab
  461.     mov    al,ah
  462.     mov    cl,3
  463.     shr    ah,cl            ;Move bit 3 down to bit 0
  464.     jmp    short RegImm
  465.  
  466. MovAcc:
  467.     mov    bx,offset DGroup:MovOp
  468.     call    CopyMsgTab
  469.     test    ah,2            ;To accumulator?
  470.     jz    ToAcc
  471.     push    ax
  472.     mov    al,"["
  473.     stosb
  474.     call    WordImm
  475.     mov    ax,",]"
  476.     stosw
  477.     pop    ax            ;Get byte/word flag back
  478.     xor    al,al            ;Use al/ax
  479.     jmp    ShowReg
  480.  
  481. ToAcc:
  482.     xor    al,al            ;Use al/ax
  483.     call    ShowReg
  484.     mov    ax,"[,"
  485.     stosw
  486.     call    WordImm
  487.     mov    al,"]"
  488.     stosb
  489.     ret
  490.  
  491. ArithIm:
  492.     mov    bx,[bx].ArithOps
  493.     call    CopyMsgTab
  494.     mov    al,0            ;Select al, ax, or eax
  495. RegImm:
  496.     call    ShowReg
  497. ShowImm:
  498.     mov    al,","
  499.     stosb
  500.     add    si,cx
  501.     push    si
  502. ImmLp:
  503.     dec    si
  504.     mov    al,ds:[si]
  505.     call    HexByteDis
  506.     loop    ImmLp
  507.     pop    si
  508.     ret    
  509.  
  510. Group3:
  511.     mov    bx,offset DGroup:tGrp3Ops
  512.     call    IndexRm
  513.     push    ax
  514.     call    ModRmSize
  515.     pop    ax
  516.     and    al,7*8            ;Mask to operation bits
  517.     cmp    al,1            ;Is it TEST?
  518.     jbe    ShowImm            ;Yes, has immediate value
  519.     ret
  520.  
  521. MovImMem:
  522.     mov    bx,offset DGroup:MovOp
  523.     call    CopyMsgTab
  524.     lodsb
  525.     call    ModRm
  526.     jmp    ShowImm
  527.  
  528. Coprocessor:
  529.     mov    bx,offset DGroup:EscOp
  530.     call    CopyMsgTab
  531.     lodsb                ;Get R/M byte
  532.     push    ax
  533.     and    ax,7*8+700H        ;Get middle bits of al, low bits of ah
  534.     shl    al,1            ;Now in high nybble
  535.     or    al,ah
  536.     call    HexByteDis
  537.     mov    al,","
  538.     stosb
  539.     pop    ax
  540.     jmp    ModRm
  541.  
  542. Group4:
  543.     mov    bx,offset DGroup:tGrp4Ops
  544.     call    IndexRm
  545.     push    ax
  546. ;Look for far call (3*8) and far jump (5*8)
  547.     sub    al,3*8            ;Now 0*8 or 2*8
  548.     and    al,5*8            ;Get middle bits
  549.     jnz    @F
  550.     or    [Prefix],fData32    ;Set operand size to dword
  551. @@:
  552.     pop    ax
  553.     call    ModRmSize
  554. Ret1:
  555.     ret
  556.  
  557. AamAad:
  558.     mov    bx,[bx].AamAadOps
  559.     call    CopyMsg
  560.     lodsb                ;Next byte "should" be 10
  561.     cmp    al,10            ;Standard instruction?
  562.     jz    Ret1
  563.     push    ax            ;Save value
  564.     mov    al,9
  565.     stosb
  566.     pop    ax
  567.     jmp    HexByteDis
  568.  
  569. InOut:
  570.     mov    bx,[bx].InOutOps
  571.     call    CopyMsgTab
  572.     test    ah,2            ;IN instruction?
  573.     jnz    ShowPort
  574. AxInpOut:
  575.     xor    al,al            ;Select al/ax
  576.     push    ax
  577.     call    ShowReg
  578.     pop    ax
  579.     test    ah,2            ;IN instruction?
  580.     jnz    Ret1            ;No, already did port
  581.     mov    al,","
  582.     stosb
  583. ShowPort:
  584.     push    ax
  585.     test    ah,8            ;Immediate port?
  586.     jz    ImmedPort
  587.     mov    ax,"xd"
  588.     stosw
  589.     jmp    short PortDone
  590.  
  591. ImmedPort:
  592.     call    ByteImm
  593. PortDone:
  594.     pop    ax
  595.     test    ah,2            ;IN instruction?
  596.     jz    Ret1            ;Yes, already did register
  597.     mov    al,","
  598.     stosb
  599.     jmp    AxInpOut
  600.  
  601. String:
  602.     mov    bx,[bx].StringOps
  603.     call    CopyMsg
  604.     mov    al,"b"            ;Assume byte version
  605.     test    ah,1            ;word/dword?
  606.     jz    StrTyp
  607.     mov    al,"d"
  608.     test    [Prefix],fData32
  609.     jnz    StrTyp
  610.     mov    al,"w"
  611. StrTyp:
  612.     stosb
  613. TabOverride:
  614.     cmp    [Override],0        ;Segment override present?
  615.     jz    NoOver
  616.     mov    al,9
  617.     stosb
  618. SegOverride:
  619.     mov    bl,[Override]
  620.     cmp    bl,0            ;Segment override present?
  621.     jz    NoOver
  622.     mov    bh,0
  623.     shl    bx,1
  624.     mov    ax,[bx-2].tSegReg
  625.     stosw
  626.     mov    al,":"
  627.     stosb
  628. NoOver:
  629.     ret
  630.  
  631. XlatInst:
  632.     mov    bx,offset DGroup:XlatOp
  633.     call    CopyMsg
  634.     jmp    TabOverride
  635.  
  636. SegPush:
  637.     mov    bx,[bx].SegPushOps
  638.     call    CopyMsgTab
  639.     mov    al,ah
  640.     and    ax,18H            ;Mask to seg reg bits
  641.     shr    ax,1
  642.     shr    ax,1
  643.     xchg    bx,ax
  644.     mov    ax,[bx].tSegReg
  645.     stosw
  646.     ret
  647.  
  648. OneReg:
  649.     mov    bx,[bx].OneRegOps    ;Point to opcode
  650.     call    CopyMsgTab
  651.     mov    al,ah
  652.     mov    ah,1            ;Indicate word operation
  653.     jmp    ShowReg
  654.  
  655.  
  656. XchgAx:
  657.     mov    bx,offset DGroup:XchgOp
  658.     call    CopyMsgTab
  659.     mov    al,ah
  660.     mov    ah,1            ;Word reg
  661.     push    ax
  662.     mov    ax,"xa"
  663.     stosw
  664.     jmp    short SecondReg
  665.  
  666. LdPointer:
  667.     mov    bx,[bx].LdPointerOps    ;Point to opcode
  668.     or    ah,3            ;Set WORD, to CPU
  669.     jmp    short RegMem
  670.  
  671. Arith:
  672.     mov    bx,[bx].ArithOps    ;Point to opcode
  673. RegMem:
  674.     call    CopyMsgTab
  675.     lodsb                ;Get R/M byte
  676.     mov    dl,al
  677.     mov    cl,3
  678.     shr    al,cl            ;Put register in low end
  679.     test    ah,2            ;Check direction
  680.     jnz    ToCpu
  681.     push    ax
  682.     xchg    al,dl
  683.     call    ModRm
  684. SecondReg:
  685.     mov    al,","
  686.     stosb
  687.     pop    ax
  688.     jmp    ShowReg
  689.  
  690. ToCpu:
  691. ;List register in R/M byte first
  692.     mov    dh,ah
  693.     push    dx
  694.     call    ShowReg
  695.     mov    al,","
  696.     stosb
  697.     pop    ax
  698.     jmp    ModRm
  699.  
  700. Jump:
  701.     mov    bx,[bx].JumpOps
  702.     call    CopyMsgTab
  703.     test    ah,2            ;Is it far?
  704.     lodsw                ;Get offset
  705.     jz    RelJump
  706.     xchg    dx,ax
  707.     call    WordImm            ;Print segment
  708.     mov    al,":"
  709.     stosb
  710.     xchg    ax,dx            ;Offset back to ax
  711.     jmp    short HexWordDis
  712.  
  713. Group2:
  714. ;Shifts
  715.     mov    bx,offset DGroup:tShiftOps
  716.     call    IndexRm
  717.     push    ax
  718.     call    ModRmSize
  719.     pop    ax
  720.     mov    al,","
  721.     stosb
  722.     test    ah,10H            ;Immediate count of shifts?
  723.     jz    ByteImm
  724.     mov    al,"1"
  725.     test    ah,2            ;One bit shift?
  726.     jz    OneChar
  727.     mov    ax,"lc"
  728.     stosw
  729.     ret
  730.  
  731. Group1:
  732. ;Arithmetic immediate
  733.     mov    bx,offset DGroup:ArithOps
  734.     call    IndexRm
  735.     push    ax
  736.     call    ModRmSize
  737.     pop    ax
  738.     mov    al,","
  739.     stosb
  740.     test    ah,1
  741.     jz    ByteImm
  742.     test    ah,2
  743.     jz    WordImm
  744.     lodsb                ;Get 8-bit displacement
  745. SignedByte:
  746.     mov    ah,al
  747.     or    al,al            ;Check sign
  748.     mov    al,"+"
  749.     jns    @F
  750.     mov    al,"-"
  751.     neg    ah
  752. @@:
  753.     stosb                ;Store sign
  754.     xchg    al,ah
  755.     jmp    short HexByteDis
  756.  
  757. ByteImm:
  758.     lodsb
  759.     jmp    short HexByteDis
  760.  
  761. RetImm:
  762.     mov    bx,[bx].RetImmOps
  763.     call    CopyMsgTab
  764. WordImm:
  765.     lodsw
  766.     jmp    short HexWordDis
  767.  
  768. CondJump2:
  769.     mov    bx,[bx].CondJump2Ops    ;Point to opcode
  770.     jmp    short AllCondJump
  771.  
  772. CondJump:
  773.     mov    bx,[bx].CondJumpOps    ;Point to opcode
  774. AllCondJump:
  775.     call    CopyMsgTab
  776.     lodsb                ;Get displacement
  777.     cbw
  778. RelJump:
  779.     add    ax,si            ;Compute target address
  780. HexWordDis:
  781. ;Convert word in ax to ASCII hex and store
  782.     mov    cl,al
  783.     mov    al,ah
  784.     call    HexByteDis
  785.     mov    al,cl
  786. HexByteDis:
  787. ;Convert byte in al to ASCII hex and store
  788.     mov    ah,al
  789.     shr    al,1
  790.     shr    al,1
  791.     shr    al,1
  792.     shr    al,1
  793.     call    Nybble
  794.     mov    al,ah
  795. Nybble:
  796. ;Convert low nybble in AL to hex and stosb
  797.     and    al,0FH
  798.     cmp    al,10
  799.     sbb    al,69H
  800.     das
  801. OneChar:
  802.     stosb
  803.     ret
  804.  
  805. Interrupt:
  806.     mov    bx,offset DGroup:IntOp
  807.     call    CopyMsgTab
  808.     test    ah,1            ;With immediate byte?
  809.     jnz    ByteImm
  810.     mov    al,"3"
  811.     stosb
  812.     ret
  813.  
  814. CopyMsgTab:
  815.     call    CopyMsg
  816.     mov    al,9
  817.     stosb
  818.     ret
  819.  
  820. OneByte2:
  821.     mov    bx,[bx].OneByte2Ops    ;Point to opcode
  822.     jmp    short CopyMsg
  823.  
  824. OneByte:
  825.     mov    bx,[bx].OneByteOps    ;Point to opcode
  826.     jmp    short CopyMsg
  827.  
  828. CopyMore:
  829.     stosb
  830. CopyMsg:
  831.     mov    al,DGroup:[bx]
  832.     inc    bx
  833.     or    al,al            ;End of string?
  834.     jns    CopyMore
  835.     and    al,7FH
  836.     stosb
  837.     ret
  838.  
  839. IndexRm:
  840.     lodsb                ;Get R/M byte
  841.     mov    dl,al
  842.     and    al,7*8            ;Mask to operation field
  843.     shr    al,1
  844.     shr    al,1
  845.     add    bl,al
  846.     adc    bh,0
  847.     mov    bx,cs:[bx]
  848.     call    CopyMsgTab
  849.     mov    al,dl            ;R/M byte back to al
  850.     ret
  851.  
  852. ;****************************************************************************
  853.     subttl    ModRm, ModRmSize, and ShowReg
  854.     page
  855.  
  856. ;ModRm displays a memory or register operand.
  857. ;
  858. ;ModRmSize includes a leading "byte ptr" (or whatever) to indicate size
  859. ;if the operand is not a register.
  860. ;
  861. ;ShowReg looks up a register.
  862. ;
  863. ;As always, ds:si points to code to disassemble, es:di points to destination
  864. ;buffer.  These pointers will be updated as appropriate.
  865.  
  866.  
  867. ModRmSize:
  868.     mov    cl,1            ;Indicate a size is needed
  869.     jmp    short ModRmCommon
  870.  
  871. ModRm:
  872. ;Inputs:
  873. ;    al = R/M byte
  874. ;    ah bit 1 has word flag (0 = byte)
  875. ;Outputs:
  876. ;    cx = no. of bytes in operand
  877.  
  878.     xor    cx,cx            ;Operand size not needed
  879. ModRmCommon:
  880.     and    al,0C7H            ;Mask out middle bits
  881.     cmp    al,0C0H            ;Register mode?
  882.     jb    MemOp
  883.  
  884. ShowReg:
  885. ;Display general register
  886. ;Inputs:
  887. ;    al bits 0 - 2 have register number
  888. ;    ah bit 1 has word flag (0 = byte)
  889. ;Outputs:
  890. ;    cx = no. of bytes in register
  891.  
  892.     and    al,7            ;Get register
  893.     mov    bl,al
  894.     mov    bh,0
  895.     shl    bx,1            ;Word index into register
  896.     and    ah,1            ;Byte size?
  897.     mov    cl,ah
  898.     mov    ch,0
  899.     jz    RegIndex
  900.     add    bx,offset tWordReg - offset tByteReg
  901.     test    [Prefix],fData32
  902.     jz    RegIndex
  903.     mov    al,"e"
  904.     stosb
  905.     mov    cl,3
  906. RegIndex:
  907.     inc    cx
  908.     mov    ax,[bx].tByteReg
  909.     stosw
  910.     ret
  911.  
  912. MemOp:
  913.     push    ax
  914.     mov    bx,offset DGroup:ByteMsg
  915.     mov    dx,1
  916.     test    ah,1            ;Check word bit
  917.     jz    ShowMemSize
  918.     mov    bx,offset DGroup:WordMsg
  919.     inc    dx
  920.     test    [Prefix],fData32    ;32-bit data mode?
  921.     jz    ShowMemSize
  922.     mov    bx,offset DGroup:DwordMsg
  923.     inc    dx
  924.     inc    dx
  925. ShowMemSize:
  926.     jcxz    NoMemSize
  927.     call    CopyMsg
  928.     mov    bx,offset DGroup:PtrMsg
  929.     call    CopyMsg
  930. NoMemSize:
  931.     call    SegOverride
  932.     mov    al,"["
  933.     stosb
  934.     pop    ax
  935.     test    [Prefix],fAddr32    ;32-bit address mode?
  936.     jnz    Addr32
  937.     cmp    al,6            ;Direct address mode?
  938.     jz    Disp16
  939.     mov    ch,al
  940.     and    al,7
  941.     mov    bx,offset DGroup:AddrMod16
  942.     xlat    AddrMod16        ;Get address registers
  943.     mov    cl,al
  944.     test    cl,AddrBp
  945.     jnz    UseBp
  946.     test    cl,AddrBx
  947.     jz    TestAddrSi
  948.     mov    ax,"xb"
  949.     stosw
  950. TestPlus:
  951.     test    cl,AddrPlus
  952.     jz    DispTest
  953.     mov    al,"+"
  954.     stosb
  955. TestAddrSi:
  956.     test    cl,AddrSi
  957.     jnz    UseSi
  958.     test    cl,AddrDi
  959.     jz    DispTest
  960.     mov    ax,"id"
  961.     stosw
  962. DispTest:
  963.     and    ch,0C0H            ;Displacement?
  964.     jz    EndMem
  965.     mov    al,"+"
  966.     js    AddDisp16
  967.     lodsb
  968.     cbw
  969.     call    SignedByte
  970. EndMem:
  971.     mov    cx,dx            ;Operand size to cx
  972.     mov    al,"]"
  973.     stosb
  974.     ret
  975.  
  976. UseBp:
  977.     mov    ax,"pb"
  978.     stosw
  979.     jmp    TestPlus
  980.  
  981. UseSi:
  982.     mov    ax,"is"
  983.     stosw
  984.     jmp    DispTest
  985.  
  986. Addr32:
  987. ;UNDONE
  988.  
  989. AddDisp16:
  990.     stosb
  991. Disp16:
  992.     lodsw                ;Get 16-bit displacement
  993.     call    HexWordDis
  994.     jmp    EndMem
  995.  
  996.  
  997.     end
  998.