Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  1. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  2. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; DISASSEMBLER ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  3. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  4.  
  5. ; TODO: prepare to work independently from debugger
  6.  
  7. ;-----------------------------------------------------------------------------
  8. ;                      Read next byte for disassembly
  9. ;
  10. ; out: AL = byte
  11. disasm_get_byte:
  12.         push    ecx
  13.         mov     ecx, [disasm_cur_pos]
  14.         sub     ecx, [disasm_start_pos]
  15.         cmp     ecx, [disasm_buf_size]
  16.         jae     disasm_err
  17.         mov     al, [disasm_buffer+ecx]
  18.         pop     ecx
  19.         inc     [disasm_cur_pos]
  20.         ret
  21.  
  22. ;-----------------------------------------------------------------------------
  23. ;                      Read next word for disassembly
  24. ;
  25. ; out: AX = word
  26. disasm_get_word:
  27.         push    ecx
  28.         mov     ecx, [disasm_cur_pos]
  29.         sub     ecx, [disasm_start_pos]
  30.         inc     ecx
  31.         cmp     ecx, [disasm_buf_size]
  32.         jae     disasm_err
  33.         mov     ax, word [disasm_buffer-1+ecx]
  34.         pop     ecx
  35.         add     [disasm_cur_pos], 2
  36.         ret
  37.  
  38. ;-----------------------------------------------------------------------------
  39. ;                     Read next dword for disassembly
  40. ;
  41. ; out: EAX = dword
  42. disasm_get_dword:
  43.         push    ecx
  44.         mov     ecx, [disasm_cur_pos]
  45.         sub     ecx, [disasm_start_pos]
  46.         add     ecx, 3
  47.         cmp     ecx, [disasm_buf_size]
  48.         jae     disasm_err
  49.         mov     eax, dword [disasm_buffer-3+ecx]
  50.         pop     ecx
  51.         add     [disasm_cur_pos], 4
  52.         ret
  53.  
  54. ;-----------------------------------------------------------------------------
  55.  
  56. disasm_err:
  57.         mov     esp, ebp
  58.  
  59. ; TODO: make it local?
  60. stc_ret:
  61.         stc
  62.         ret
  63.  
  64. ;-----------------------------------------------------------------------------
  65. ;                       Exit from disassembly loop
  66.  
  67. disasm_ret:
  68.         mov     esp, ebp
  69.         and     byte [edi], 0
  70.         ret
  71.  
  72. ;-----------------------------------------------------------------------------
  73. ;                       Disassembly one instruction
  74. ;
  75. ; Read data, in loop, to read multibyte instruction opcodes
  76.  
  77. disasm_instr:
  78.         mov     ebp, esp
  79.         cmp     [debuggee_pid], 0
  80.         jz      stc_ret
  81.         mov     edi, disasm_string
  82.         xor     ecx, ecx
  83.  
  84. ; TODO: make it local?
  85. ; ecx=flags (IN or OUT?)
  86. disasm_loop1:
  87.         xor     eax, eax
  88.         call    disasm_get_byte
  89.         jmp     dword [disasm_table_1 + eax*4]
  90.  
  91. ;-----------------------------------------------------------------------------
  92.  
  93. cop0:
  94. clock:
  95. csegcs:
  96. csegds:
  97. cseges:
  98. csegss:
  99. csegfs:
  100. cseggs:
  101.         mov     esi, cmd1
  102.  
  103. iglobal
  104. cmd1:
  105.         db      0x2E,3,'cs:'
  106.         db      0x36,3,'ss:'
  107.         db      0x3E,3,'ds:'
  108.         db      0x26,3,'es:'
  109.         db      0x64,3,'fs:'
  110.         db      0x65,3,'gs:'
  111.         db      0x06,10,'push    es'
  112.         db      0x07,10,'pop     es'
  113.         db      0x0E,10,'push    cs'
  114.         db      0x16,10,'push    ss'
  115.         db      0x17,10,'pop     ss'
  116.         db      0x1E,10,'push    ds'
  117.         db      0x1F,10,'pop     ds'
  118.         db      0x27,3,'daa'
  119.         db      0x2F,3,'das'
  120.         db      0x37,3,'aaa'
  121.         db      0x3F,3,'aas'
  122.         db      0x60,6,0,'pusha'
  123.         db      0x61,5,0,'popa'
  124.         db      0x90,3,'nop'
  125.         db      0x9B,5,'fwait'
  126.         db      0x9C,6,0,'pushf'
  127.         db      0x9D,5,0,'popf'
  128.         db      0x9E,4,'sahf'
  129.         db      0x9F,4,'lahf'
  130.         db      0xA4,5,'movsb'
  131.         db      0xA5,5,0,'movs'
  132.         db      0xA6,5,'cmpsb'
  133.         db      0xA7,5,0,'cmps'
  134.         db      0xAA,5,'stosb'
  135.         db      0xAB,5,0,'stos'
  136.         db      0xAC,5,'lodsb'
  137.         db      0xAD,5,0,'lods'
  138.         db      0xAE,5,'scasb'
  139.         db      0xAF,5,0,'scas'
  140.         db      0xC3,3,'ret'
  141.         db      0xC9,5,'leave'
  142.         db      0xCC,4,'int3'
  143.         db      0xF0,4,'lock'
  144.         db      0xF5,3,'cmc'
  145.         db      0xF8,3,'clc'
  146.         db      0xF9,3,'stc'
  147.         db      0xFA,3,'cli'
  148.         db      0xFB,3,'sti'
  149.         db      0xFC,3,'cld'
  150.         db      0xFD,3,'std'
  151.  
  152. cmd2:
  153.         db      0x05,7,'syscall'
  154.         db      0x06,4,'clts'
  155.         db      0x31,5,'rdtsc'
  156.         db      0x34,8,'sysenter'
  157.         db      0xA2,5,'cpuid'
  158.         db      0x77,4,'emms'
  159.  
  160. endg
  161.         jmp     @f
  162.  
  163. ;-----------------------------------------------------------------------------
  164.  
  165. ccpuid:
  166. crdtsc:
  167. cemms:
  168. cop0_F:
  169.         mov     esi, cmd2
  170.  
  171.     @@:
  172.         cmp     al, [esi]
  173.         jz      .found
  174.         inc     esi
  175.         movzx   edx, byte [esi]
  176.         inc     esi
  177.         add     esi, edx
  178.         jmp     @b
  179.  
  180.     .found:
  181.         inc     esi
  182.         lodsb
  183.         cmp     byte [esi], 0
  184.         jz      @f
  185.         movzx   ecx, al
  186.  
  187.     disasm_1:
  188.         rep movsb
  189.         and     byte [edi], 0
  190.         ret
  191.  
  192.     @@:
  193.         mov     dl, ch
  194.         movzx   ecx, al
  195.         dec     ecx
  196.         inc     esi
  197.         rep movsb
  198.         test    dl, 1
  199.         mov     al, 'w'
  200.         jnz     @f
  201.         mov     al, 'd'
  202.  
  203.     @@:
  204.         stosb
  205.         and     byte [edi], 0
  206.         ret
  207.  
  208.     c67:
  209.         or      ch, 2
  210.         jmp     disasm_loop1
  211.  
  212.     c66:
  213.         or      ch, 1
  214.         jmp     disasm_loop1
  215.  
  216. ;-----------------------------------------------------------------------------
  217.  
  218. cxlat:
  219. cunk:
  220. cerr:
  221.         mov     eax, '???'
  222.         stosd
  223.         clc
  224.         ret
  225.  
  226. cF:
  227.         call    disasm_get_byte
  228.         jmp     dword [disasm_table_2 + eax*4]
  229.  
  230. ;-----------------------------------------------------------------------------
  231. ;                        Parse operand prefixes
  232.  
  233. crep:
  234.         push    [disasm_cur_pos]
  235.         call    disasm_get_byte
  236.         cmp     al, 0x0F
  237.         jz      .sse
  238.         mov     dl, al
  239.         mov     eax, 'rep '
  240.         stosd
  241.         mov     al, dl
  242.  
  243.     @@:
  244.         and     eax, not 1
  245.         cmp     al, 0x66
  246.         jnz     @f
  247.         call    disasm_get_byte
  248.         mov     dl, al
  249.         jmp     @b
  250.  
  251.     @@:
  252.         cmp     al, 0xA6
  253.         jz      .repz
  254.         cmp     al, 0xAE
  255.         jz      .repz
  256.         cmp     al, 0xA4
  257.         jz      .prefix
  258.         cmp     al, 0xAA
  259.         jz      .prefix
  260.         cmp     al, 0xAC
  261.         jz      .prefix
  262.         cmp     al, 0x6C
  263.         jz      .prefix
  264.         cmp     al, 0x6E
  265.         jz      .prefix
  266.  
  267.     .noprefix:
  268.         pop     [disasm_cur_pos]
  269.         and     byte [edi-1], 0
  270.         ret
  271.  
  272.     .repz:
  273.         mov     byte [edi-1], 'z'
  274.         mov     al, ' '
  275.         stosb
  276.  
  277.     .prefix:
  278.         pop     [disasm_cur_pos]
  279.         jmp     disasm_loop1
  280.  
  281.     .sse:
  282.         pop     eax
  283.         call    disasm_get_byte
  284.  
  285. ;-----------------------------------------------------------------------------
  286.  
  287. iglobal
  288. rep_sse_cmds:
  289.         db      0x58,3,'add'
  290.         db      0xC2,3,'cmp'
  291.         db      0,0
  292. endg
  293.         mov     esi, rep_sse_cmds+1
  294.  
  295.     @@:
  296.         movzx   edx, byte [esi]
  297.         cmp     al, [esi-1]
  298.         jz      @f
  299.         lea     esi, [esi+edx+2]
  300.         cmp     byte [esi], 0
  301.         jnz     @b
  302.         sub     [disasm_cur_pos], 2
  303.         mov     eax, 'rep'
  304.         stosd
  305.         ret
  306.  
  307.     @@:
  308.         push    ecx
  309.         mov     ecx, edx
  310.         inc     esi
  311.         rep movsb
  312.         pop     ecx
  313.         mov     al, 's'
  314.         stosb
  315.         jmp     rep_sse_final
  316.  
  317. ;-----------------------------------------------------------------------------
  318.  
  319. crepnz:
  320.         call    disasm_get_byte
  321.         cmp     al, 0x0F
  322.         jz      .sse
  323.         mov     dl, al
  324.         mov     eax, 'repn'
  325.         stosd
  326.         mov     al, 'z'
  327.         stosb
  328.         mov     al, ' '
  329.         stosb
  330.         movzx   eax, dl
  331.         cmp     al, 0x6C
  332.         jb      crep.noprefix
  333.         cmp     al, 0x6F
  334.         jbe     .prefix
  335.         cmp     al, 0xA4
  336.         jb      crep.noprefix
  337.         cmp     al, 0xA7
  338.         jbe     .prefix
  339.         cmp     al, 0xAA
  340.         jb      crep.noprefix
  341.         cmp     al, 0xAF
  342.         ja      crep.noprefix
  343.  
  344.     .prefix:
  345.         jmp     cop0
  346.  
  347.     .sse:
  348.         call    disasm_get_byte
  349.         mov     esi, rep_sse_cmds+1
  350.  
  351.     @@:
  352.         movzx   edx, byte [esi]
  353.         cmp     al, [esi-1]
  354.         jz      .found0
  355.         lea     esi, [esi+edx+2]
  356.         cmp     byte [esi], 0
  357.         jnz     @b
  358.         mov     esi, sse_cmds2+1
  359.  
  360.     @@:
  361.         movzx   edx, byte [esi]
  362.         cmp     al, [esi-1]
  363.         jz      .found1
  364.         lea     esi, [esi+edx+2]
  365.         cmp     byte [esi], 0
  366.         jnz     @b
  367.         sub     [disasm_cur_pos], 2
  368.         mov     eax, 'repn'
  369.         stosd
  370.         mov     al, 'z'
  371.         stosb
  372.         and     byte [edi], 0
  373.         ret
  374.  
  375.     .found0:
  376.         push    ecx
  377.         mov     ecx, edx
  378.         inc     esi
  379.         rep movsb
  380.         pop     ecx
  381.         mov     al, 's'
  382.         stosb
  383.         mov     al, 'd'
  384.         jmp     rep_sse_final
  385.  
  386.     .found1:
  387.         push    ecx
  388.         mov     ecx, edx
  389.         inc     esi
  390.         rep movsb
  391.         pop     ecx
  392.         mov     al, 'p'
  393.         stosb
  394.         mov     al, 's'
  395.  
  396.     rep_sse_final:
  397.         stosb
  398.         push    ecx
  399.         push    5
  400.         pop     ecx
  401.         sub     ecx, edx
  402.         adc     ecx, 1
  403.         mov     al, ' '
  404.         rep stosb
  405.         pop     ecx
  406.         or      ch, 1
  407.         jmp     disasm_mmx1
  408.  
  409. ;-----------------------------------------------------------------------------
  410.  
  411. macro disasm_set_modew
  412. {
  413.         test    al, 1
  414.         jz      @f
  415.         or      ch, 80h
  416.     @@:
  417. }
  418.  
  419. ;-----------------------------------------------------------------------------
  420.  
  421. cmov2:
  422.         disasm_set_modew
  423.     ; mov r/m,i
  424.         call    disasm_get_byte
  425.         dec     [disasm_cur_pos]
  426.         test    al, 00111000b
  427.         jnz     cunk
  428.         mov     eax, 'mov '
  429.         stosd
  430.         mov     eax, '    '
  431.         stosd
  432.         call    disasm_readrmop
  433.         mov     ax, ', '
  434.         stosw
  435.         xor     eax, eax
  436.         test    ch, 80h
  437.         jnz     .1
  438.         call    disasm_get_byte
  439.         jmp     .3
  440.  
  441.     .1:
  442.         test    ch, 1
  443.         jnz     .2
  444.         call    disasm_get_dword
  445.         jmp     .3
  446.  
  447.     .2:
  448.         call    disasm_get_word
  449.  
  450.     .3:
  451.         call    disasm_write_num
  452.         and     byte [edi], 0
  453.         ret
  454.  
  455. ;-----------------------------------------------------------------------------
  456.  
  457. cret2:
  458.         mov     eax, 'ret '
  459.         stosd
  460.         mov     eax, '    '
  461.         stosd
  462.         xor     eax, eax
  463.         jmp     cmov2.2
  464.  
  465. ;-----------------------------------------------------------------------------
  466.  
  467. disasm_write_num:
  468.         push    esi
  469.         cmp     eax, 0x80
  470.         jl      .nosymb
  471.         lea     esi, [eax-1]
  472.         test    eax, esi
  473.         jz      .nosymb
  474.         call    find_symbol
  475.         jc      .nosymb
  476.  
  477.     @@:
  478.         lodsb
  479.         test    al, al
  480.         jz      @f
  481.         stosb
  482.         jmp     @b
  483.  
  484.     @@:
  485.         pop     esi
  486.         ret
  487.  
  488.     .nosymb:
  489.         pop     esi
  490.         push    ecx eax
  491.         inc     edi
  492.  
  493.     @@:
  494.         mov     ecx, eax
  495.         shr     eax, 4
  496.         jz      @f
  497.         inc     edi
  498.         jmp     @b
  499.  
  500.     @@:
  501.         pop     eax
  502.         cmp     ecx, 10
  503.         jb      @f
  504.         inc     edi
  505.  
  506.     @@:
  507.         push    edi eax
  508.  
  509.     @@:
  510.         mov     ecx, eax
  511.         and     al, 0xF
  512.         cmp     al, 10
  513.         sbb     al, 69h
  514.         das
  515.         dec     edi
  516.         mov     [edi], al
  517.         mov     eax, ecx
  518.         shr     eax, 4
  519.         jnz     @b
  520.         cmp     ecx, 10
  521.         jb      @f
  522.         mov     byte [edi-1], '0'
  523.  
  524.     @@:
  525.         pop     eax edi ecx
  526.         cmp     eax, 10
  527.         jb      @f
  528.         mov     byte [edi], 'h'
  529.         inc     edi
  530.  
  531.     @@:
  532.         ret
  533.  
  534. ;-----------------------------------------------------------------------------
  535.  
  536. iglobal
  537. label disasm_regs32 dword
  538. label disasm_regs dword
  539.         db      'eax',0
  540.         db      'ecx',0
  541.         db      'edx',0
  542.         db      'ebx',0
  543.         db      'esp',0
  544.         db      'ebp',0
  545.         db      'esi',0
  546.         db      'edi',0
  547.  
  548. disasm_regs16   dw      'ax','cx','dx','bx','sp','bp','si','di'
  549. disasm_regs8    dw      'al','cl','dl','bl','ah','ch','dh','bh'
  550. disasm_scale    db      '1248'
  551. endg
  552.  
  553. ;-----------------------------------------------------------------------------
  554.  
  555. disasm_readrmop:
  556.         call    disasm_get_byte
  557.         test    ch, 40h
  558.         jnz     .skip_size
  559.         push    eax
  560.         and     al, 0xC0
  561.         cmp     al, 0xC0
  562.         pop     eax
  563.         jz      .skip_size
  564.         test    ch, 80h
  565.         jz      .byte
  566.         test    ch, 1
  567.         jnz     .word
  568.         mov     dword [edi], 'dwor'
  569.         mov     byte [edi+4], 'd'
  570.         inc     edi
  571.         jmp     @f
  572.  
  573.     .byte:
  574.         test    ch, 20h
  575.         jz      .qb
  576.         mov     byte [edi], 't'
  577.         inc     edi
  578.  
  579.     .qb:
  580.         mov     dword [edi], 'byte'
  581.         jmp     @f
  582.  
  583.     .word:
  584.         test    ch, 20h
  585.         jz      .qw
  586.         mov     byte [edi], 'q'
  587.         inc     edi
  588.  
  589.     .qw:
  590.         mov     dword [edi], 'word'
  591.  
  592.     @@:
  593.         mov     byte [edi+4], ' '
  594.         add     edi, 5
  595.  
  596.     .skip_size:
  597.         test    ch, 2
  598.         jnz     disasm_readrmop16
  599.         push    ecx
  600.         movzx   ecx, al
  601.         and     eax, 7
  602.         shr     ecx, 6
  603.         jz      .vmod0
  604.         jp      .vmod3
  605.         mov     byte [edi], '['
  606.         inc     edi
  607.         cmp     al, 4
  608.         jz      .sib1
  609.         mov     eax, [disasm_regs+eax*4]
  610.         stosd
  611.         dec     edi
  612.         jmp     @f
  613.  
  614.     .sib1:
  615.         call    .parse_sib
  616.  
  617.     @@:
  618.         mov     al, '+'
  619.         stosb
  620.         dec     ecx
  621.         jz      .vmod1
  622.         call    disasm_get_dword
  623.         jmp     @f
  624.  
  625.     .vmod1:
  626.         call    disasm_get_byte
  627.         movsx   eax, al
  628.  
  629.     @@:
  630.         test    eax, eax
  631.         jns     .2
  632.         neg     eax
  633.         mov     byte [edi-1], '-'
  634.  
  635.     .2:
  636.         call    disasm_write_num
  637.  
  638.     .2a:
  639.         mov     al, ']'
  640.         stosb
  641.         pop     ecx
  642.         ret
  643.  
  644.     .vmod3:
  645.         pop     ecx
  646.         test    ch, 10h
  647.         jnz     .vmod3_mmi
  648.         test    ch, 80h
  649.         jz      .vmod3_byte
  650.         test    ch, 1
  651.         jnz     .vmod3_word
  652.         test    ch, 20h
  653.         jnz     .vmod3_sti
  654.         mov     eax, [disasm_regs32+eax*4]
  655.         stosd
  656.         dec     edi
  657.         ret
  658.  
  659.     .vmod3_byte:
  660.         mov     ax, [disasm_regs8+eax*2]
  661.  
  662.     @@:
  663.         stosw
  664.         ret
  665.  
  666.     .vmod3_word:
  667.         mov     ax, [disasm_regs16+eax*2]
  668.         jmp     @b
  669.  
  670.     .vmod3_sti:
  671.         mov     word [edi], 'st'
  672.         add     al, '0'
  673.         mov     byte [edi+2], al
  674.         add     edi, 3
  675.         ret
  676.  
  677.     .vmod3_mmi:
  678.    
  679.     disasm_write_mmreg = $
  680.  
  681.         test    ch, 1
  682.         jz      @f
  683.         mov     byte [edi], 'x'
  684.         inc     edi
  685.  
  686.     @@:
  687.         mov     word [edi], 'mm'
  688.         add     al, '0'
  689.         mov     byte [edi+2], al
  690.         add     edi, 3
  691.         ret
  692.  
  693.     .vmod0:
  694.         mov     byte [edi], '['
  695.         inc     edi
  696.         cmp     al, 4
  697.         jz      .sib2
  698.         cmp     al, 5
  699.         jz      .ofs32
  700.         mov     eax, [disasm_regs+eax*4]
  701.         stosd
  702.         mov     byte [edi-1], ']'
  703.         pop     ecx
  704.         ret
  705.  
  706.     .ofs32:
  707.         call    disasm_get_dword
  708.         jmp     .2
  709.  
  710.     .sib2:
  711.         call    .parse_sib
  712.         mov     al, ']'
  713.         stosb
  714.         pop     ecx
  715.         ret
  716.  
  717.     .parse_sib:
  718.         call    disasm_get_byte
  719.         push    edx
  720.         mov     dl, al
  721.         mov     dh, 0
  722.         and     eax, 7
  723.         cmp     al, 5
  724.         jnz     @f
  725.         jecxz   .sib0
  726.  
  727.     @@:
  728.         mov     eax, [disasm_regs+eax*4]
  729.         stosd
  730.         dec     edi
  731.         mov     dh, 1
  732.  
  733.     .sib0:
  734.         mov     al, dl
  735.         shr     eax, 3
  736.         and     eax, 7
  737.         cmp     al, 4
  738.         jz      .sibret
  739.         test    dh, dh
  740.         jz      @f
  741.         mov     byte [edi], '+'
  742.         inc     edi
  743.  
  744.     @@:
  745.         mov     eax, [disasm_regs+eax*4]
  746.         stosd
  747.         dec     edi
  748.         shr     dl, 6
  749.         jz      @f
  750.         mov     al, '*'
  751.         stosb
  752.         movzx   eax, dl
  753.         mov     al, [disasm_scale+eax]
  754.         stosb
  755.  
  756.     @@:
  757.     .sibret:
  758.         test    dh, dh
  759.         jnz     .sibret2
  760.         call    disasm_get_dword
  761.         cmp     byte [edi-1], '['
  762.         jz      @f
  763.         mov     byte [edi], '+'
  764.         test    eax, eax
  765.         jns     .sibns
  766.         neg     eax
  767.         mov     byte [edi], '-'
  768.  
  769.     .sibns:
  770.         inc     edi
  771.  
  772.     @@:
  773.         call    disasm_write_num
  774.  
  775.     .sibret2:
  776.         pop     edx
  777.         ret
  778.  
  779. ;-----------------------------------------------------------------------------
  780.  
  781. iglobal
  782. disasm_rm16_1   dd      'bxsi','bxdi','bpsi','bpdi'
  783. disasm_rm16_2   dw      'si','di','bp','bx'
  784. endg
  785.  
  786. ;-----------------------------------------------------------------------------
  787.  
  788. disasm_readrmop16:
  789.         push    ecx
  790.         movzx   ecx, al
  791.         and     eax, 7
  792.         shr     ecx, 6
  793.         jz      .vmod0
  794.         jp      disasm_readrmop.vmod3   ; mod=3 is the same in 16- and 32-bit code
  795.     ; 1 or 2
  796.         mov     byte [edi], '['
  797.         inc     edi
  798.         cmp     al, 4
  799.         jae     @f
  800.         mov     eax, [disasm_rm16_1+eax*4]
  801.         stosw
  802.         mov     al, '+'
  803.         stosb
  804.         shr     eax, 16
  805.         jmp     .1
  806.  
  807.     @@:
  808.         mov     eax, dword [disasm_rm16_2+eax*2-4*2]
  809.  
  810.     .1:
  811.         stosw
  812.         mov     al, '+'
  813.         stosb
  814.         xor     eax, eax
  815.         dec     ecx
  816.         jnz     .2
  817.         call    disasm_get_byte
  818.         cbw
  819.         jmp     @f
  820.  
  821.     .2:
  822.         call    disasm_get_word
  823.  
  824.     @@:
  825.         test    ax, ax
  826.         jns     @f
  827.         mov     byte [edi-1], '-'
  828.         neg     ax
  829.  
  830.     @@:
  831.         call    disasm_write_num
  832.  
  833.     .done1:
  834.         mov     al, ']'
  835.         stosb
  836.         pop     ecx
  837.         ret
  838.  
  839.     .vmod0:
  840.         mov     byte [edi], '['
  841.         inc     edi
  842.         cmp     al, 6
  843.         jz      .ofs16
  844.         cmp     al, 4
  845.         jae     @f
  846.         mov     eax, [disasm_rm16_1+eax*4]
  847.         stosw
  848.         mov     al, '+'
  849.         stosb
  850.         shr     eax, 16
  851.         jmp     .3
  852.  
  853.     @@:
  854.         mov     eax, dword [disasm_rm16_2+eax*2-4*2]
  855.  
  856.     .3:
  857.         stosw
  858.         jmp     .done1
  859.  
  860.     .ofs16:
  861.         xor     eax, eax
  862.         call    disasm_get_word
  863.         call    disasm_write_num
  864.         jmp     .done1
  865.  
  866. ;-----------------------------------------------------------------------------
  867.  
  868. cpush21:
  869.         mov     eax, 'push'
  870.         stosd
  871.         mov     eax, '    '
  872.         stosd
  873.  
  874. disasm_i32:
  875.         call    disasm_get_dword
  876.         call    disasm_write_num
  877.         and     byte [edi], 0
  878.         ret
  879.  
  880. cpush22:
  881.         mov     eax, 'push'
  882.         stosd
  883.         mov     eax, '    '
  884.         stosd
  885.         call    disasm_get_byte
  886.         movsx   eax, al
  887.  
  888.     @@:
  889.         call    disasm_write_num
  890.         and     byte [edi], 0
  891.         ret
  892.  
  893. ;-----------------------------------------------------------------------------
  894.  
  895. center:
  896.         mov     eax, 'ente'
  897.         stosd
  898.         mov     eax, 'r   '
  899.         stosd
  900.         xor     eax, eax
  901.         call    disasm_get_word
  902.         call    disasm_write_num
  903.         mov     al, ','
  904.         stosb
  905.         mov     al, ' '
  906.         stosb
  907.         xor     eax, eax
  908.         call    disasm_get_byte
  909.         jmp     @b
  910.  
  911. ;-----------------------------------------------------------------------------
  912.  
  913. cinc1:
  914. ; inc reg32
  915. cdec1:
  916. ; dec reg32
  917. cpush1:
  918. ; push reg32
  919. cpop1:
  920. ; pop reg32
  921. cbswap:
  922. ; bswap reg32
  923.         mov     edx, eax
  924.         and     edx, 7
  925.         shr     eax, 3
  926.         sub     al, 8
  927.         mov     esi, 'inc '
  928.         jz      @f
  929.         mov     esi, 'dec '
  930.         dec     al
  931.         jz      @f
  932.         mov     esi, 'push'
  933.         dec     al
  934.         jz      @f
  935.         mov     esi, 'pop '
  936.         dec     al
  937.         jz      @f
  938.         mov     esi, 'bswa'
  939.  
  940.     @@:
  941.         xchg    eax, esi
  942.         stosd
  943.         mov     eax, '    '
  944.         jz      @f
  945.         mov     al, 'p'
  946.  
  947.     @@:
  948.         stosd
  949.         xchg    eax, edx
  950.         call    disasm_write_reg1632
  951.         and     byte [edi], 0
  952.         ret
  953.  
  954. ;-----------------------------------------------------------------------------
  955.  
  956. cxchg1:
  957. ; xchg eax,reg32
  958.         and     eax, 7
  959.         xchg    eax, edx
  960.         mov     eax, 'xchg'
  961.         stosd
  962.         mov     eax, '    '
  963.         stosd
  964.         xor     eax, eax
  965.         call    disasm_write_reg1632
  966.         mov     ax, ', '
  967.         stosw
  968.         xchg    eax, edx
  969.         call    disasm_write_reg1632
  970.         and     byte [edi], 0
  971.         ret
  972.  
  973. cint:
  974.         mov     eax, 'int '
  975.         stosd
  976.         mov     eax, '    '
  977.         stosd
  978.  
  979. disasm_i8u:
  980.         xor     eax, eax
  981.         call    disasm_get_byte
  982.         call    disasm_write_num
  983.         and     byte [edi], 0
  984.         ret
  985.  
  986. ;-----------------------------------------------------------------------------
  987.  
  988. cmov11:
  989. ; mov r8,i8
  990.         mov     ecx, eax
  991.         mov     eax, 'mov '
  992.         stosd
  993.         mov     eax, '    '
  994.         stosd
  995.         and     ecx, 7
  996.         mov     ax, [disasm_regs8+ecx*2]
  997.         stosw
  998.         mov     ax, ', '
  999.         stosw
  1000.         jmp     disasm_i8u
  1001.  
  1002. ;-----------------------------------------------------------------------------
  1003.  
  1004. cmov12:
  1005. ; mov r32,i32
  1006.         xchg    eax, edx
  1007.         mov     eax, 'mov '
  1008.         stosd
  1009.         mov     eax, '    '
  1010.         stosd
  1011.         xchg    eax, edx
  1012.         and     eax, 7
  1013.         call    disasm_write_reg1632
  1014.         mov     ax, ', '
  1015.         stosw
  1016.         jmp     cmov2.1
  1017.  
  1018. ;-----------------------------------------------------------------------------
  1019.  
  1020. iglobal
  1021. disasm_shifts   dd      'rol ','ror ','rcl ','rcr ','shl ','shr ','sal ','sar '
  1022. endg
  1023.  
  1024. ;-----------------------------------------------------------------------------
  1025.  
  1026. cshift2:
  1027. ; shift r/m,1 = D0/D1
  1028. cshift3:
  1029. ; shift r/m,cl = D2/D3
  1030.         disasm_set_modew
  1031.         mov     dl, al
  1032.         call    disasm_get_byte
  1033.         dec     [disasm_cur_pos]
  1034.         shr     al, 3
  1035.         and     eax, 7
  1036.         mov     eax, [disasm_shifts+eax*4]
  1037.         stosd
  1038.         mov     eax, '    '
  1039.         stosd
  1040.         call    disasm_readrmop
  1041.         cmp     dl, 0xD2
  1042.         jb      .s1
  1043.         mov     eax, ', cl'
  1044.         stosd
  1045.         and     byte [edi], 0
  1046.         ret
  1047.  
  1048.     .s1:
  1049.         mov     eax, ', 1'
  1050.         stosd
  1051.         clc
  1052.         ret
  1053.  
  1054. ;-----------------------------------------------------------------------------
  1055.  
  1056. cshift1:
  1057. ; shift r/m,i8 = C0/C1
  1058.         disasm_set_modew
  1059.         call    disasm_get_byte
  1060.         dec     [disasm_cur_pos]
  1061.         shr     al, 3
  1062.         and     eax, 7
  1063.         mov     eax, [disasm_shifts+eax*4]
  1064.         stosd
  1065.         mov     eax, '    '
  1066.         stosd
  1067.         call    disasm_readrmop
  1068.         mov     ax, ', '
  1069.         stosw
  1070.         jmp     disasm_i8u
  1071.  
  1072. ;-----------------------------------------------------------------------------
  1073.  
  1074. caam:
  1075.         mov     eax, 'aam '
  1076.         jmp     @f
  1077.  
  1078. caad:
  1079.         mov     eax, 'aad '
  1080.  
  1081.     @@:
  1082.         stosd
  1083.         mov     eax, '    '
  1084.         stosd
  1085.         xor     eax, eax
  1086.         call    disasm_get_byte
  1087.         cmp     al, 10
  1088.         jz      @f
  1089.         call    disasm_write_num
  1090.  
  1091.     @@:
  1092.         and     byte [edi], 0
  1093.         ret
  1094.  
  1095. ;-----------------------------------------------------------------------------
  1096.  
  1097. cmov3:
  1098. ; A0: mov al,[ofs32]
  1099. ; A1: mov ax/eax,[ofs32]
  1100. ; A2: mov [ofs32],al
  1101. ; A3: mov [ofs32],ax/eax
  1102.         mov     edx, 'mov '
  1103.         xchg    eax, edx
  1104.         stosd
  1105.         mov     eax, '    '
  1106.         stosd
  1107.         test    dl, 2
  1108.         jnz     .1
  1109.         call    .write_acc
  1110.         mov     ax, ', '
  1111.         stosw
  1112.         call    .write_ofs32
  1113.         jmp     .2
  1114.  
  1115.     .1:
  1116.         call    .write_ofs32
  1117.         mov     ax, ', '
  1118.         stosw
  1119.         call    .write_acc
  1120.  
  1121.     .2:
  1122.         and     byte [edi], 0
  1123.         ret
  1124.  
  1125.     .write_acc:
  1126.         test    dl, 1
  1127.         jz      .8bit
  1128.         test    ch, 1
  1129.         jnz     .16bit
  1130.         mov     eax, 'eax'
  1131.         stosd
  1132.         dec     edi
  1133.         ret
  1134.  
  1135.     .16bit:
  1136.         mov     ax, 'ax'
  1137.         stosw
  1138.         ret
  1139.  
  1140.     .8bit:
  1141.         mov     ax, 'al'
  1142.         stosw
  1143.         ret
  1144.  
  1145.     .write_ofs32:
  1146.         mov     al, '['
  1147.         stosb
  1148.         call    disasm_get_dword
  1149.         call    disasm_write_num
  1150.         mov     al, ']'
  1151.         stosb
  1152.         ret
  1153.  
  1154. ;-----------------------------------------------------------------------------
  1155.  
  1156. disasm_write_reg:
  1157.         test    ch, 80h
  1158.         jnz     disasm_write_reg1632
  1159.         mov     ax, [disasm_regs8+eax*2]
  1160.         stosw
  1161.         ret
  1162.  
  1163. ;-----------------------------------------------------------------------------
  1164.  
  1165. disasm_write_reg1632:
  1166.         test    ch, 1
  1167.         jnz     @f
  1168.         mov     eax, [disasm_regs32+eax*4]
  1169.         stosd
  1170.         dec     edi
  1171.         ret
  1172.  
  1173.     @@:
  1174.         mov     ax, [disasm_regs16+eax*2]
  1175.         stosw
  1176.         ret
  1177.  
  1178. ;-----------------------------------------------------------------------------
  1179.  
  1180. ; 0F B6/B7
  1181. cmovzx:
  1182. ; 0F BE/BF
  1183. cmovsx:
  1184.         mov     edx, eax
  1185.         disasm_set_modew
  1186.         mov     eax, 'movz'
  1187.         cmp     dl, 0xB8
  1188.         jb      @f
  1189.         mov     eax, 'movs'
  1190.  
  1191.     @@:
  1192.         stosd
  1193.         mov     eax, 'x   '
  1194.         stosd
  1195.         call    disasm_get_byte
  1196.         dec     [disasm_cur_pos]
  1197.         shr     al, 3
  1198.         and     eax, 7
  1199.         call    disasm_write_reg1632
  1200.         mov     ax, ', '
  1201.         stosw
  1202.         or      ch, 1   ; 2nd operand - 8 or 16 bits
  1203.         call    disasm_readrmop
  1204.         and     byte [edi], 0
  1205.         ret
  1206.  
  1207. ;-----------------------------------------------------------------------------
  1208.  
  1209. iglobal
  1210. disasm_op2cmds  dd 'add ','or  ','adc ','sbb ','and ','sub ','xor ','cmp '
  1211. endg
  1212.  
  1213. ;-----------------------------------------------------------------------------
  1214.  
  1215. cop21:
  1216.         disasm_set_modew
  1217.         mov     esi, 'test'
  1218.         cmp     al, 0A8h
  1219.         jae     @f
  1220.         shr     al, 3
  1221.         and     eax, 7
  1222.         mov     esi, [disasm_op2cmds+eax*4]
  1223.  
  1224.     @@:
  1225.         xchg    eax, esi
  1226.         stosd
  1227.         mov     eax, '    '
  1228.         stosd
  1229.         test    ch, 80h
  1230.         jnz     .1632
  1231.         mov     eax, 'al, '
  1232.         stosd
  1233.         jmp     disasm_i8u
  1234.  
  1235.     .1632:
  1236.         test    ch, 1
  1237.         jnz     .16
  1238.         mov     eax, 'eax,'
  1239.         stosd
  1240.         mov     al, ' '
  1241.         stosb
  1242.         call    disasm_get_dword
  1243.         jmp     .x
  1244.  
  1245.     .16:
  1246.         mov     eax, 'ax, '
  1247.         stosd
  1248.         xor     eax, eax
  1249.         call    disasm_get_word
  1250.  
  1251.     .x:
  1252.         call    disasm_write_num
  1253.         and     byte [edi], 0
  1254.         ret
  1255.  
  1256. ;-----------------------------------------------------------------------------
  1257.  
  1258. carpl:
  1259.         xor     edx, edx
  1260.         or      ch, 0C1h
  1261.         mov     eax, 'arpl'
  1262.         jmp     cop22.d2
  1263.  
  1264. ;-----------------------------------------------------------------------------
  1265.  
  1266. ccmpxchg:
  1267.         xor     edx, edx
  1268.         disasm_set_modew
  1269.         or      ch, 40h
  1270.         mov     eax, 'cmpx'
  1271.         stosd
  1272.         mov     eax, 'chg '
  1273.         jmp     cop22.d1
  1274.  
  1275. ;-----------------------------------------------------------------------------
  1276.  
  1277. cbsf:
  1278. cbsr:
  1279.         or      ch, 80h
  1280.  
  1281. ;-----------------------------------------------------------------------------
  1282.  
  1283. cop22:
  1284.         disasm_set_modew
  1285.         or      ch, 40h
  1286.         mov     edx, eax
  1287.         mov     esi, 'lea '
  1288.         cmp     al, 8Dh
  1289.         jz      @f
  1290.         mov     esi, 'imul'
  1291.         cmp     al, 0xAF
  1292.         jz      @f
  1293.         mov     esi, 'bsf '
  1294.         cmp     al, 0BCh
  1295.         jz      @f
  1296.         mov     esi, 'bsr '
  1297.         cmp     al, 0BDh
  1298.         jz      @f
  1299.         mov     esi, 'mov '
  1300.         cmp     al, 88h
  1301.         jae     @f
  1302.         mov     esi, 'xchg'
  1303.         cmp     al, 86h
  1304.         jae     @f
  1305.         mov     esi, 'test'
  1306.         cmp     al, 84h
  1307.         jae     @f
  1308.         shr     al, 3
  1309.         and     eax, 7
  1310.         mov     esi, [disasm_op2cmds+eax*4]
  1311.  
  1312.     @@:
  1313.         xchg    eax, esi
  1314.  
  1315.     .d2:
  1316.         stosd
  1317.         mov     eax, '    '
  1318.  
  1319.     .d1:
  1320.         stosd
  1321.         call    disasm_get_byte
  1322.         dec     [disasm_cur_pos]
  1323.         shr     al, 3
  1324.         and     eax, 7
  1325.         cmp     dl, 0x8D
  1326.         jz      @f
  1327.         cmp     dl, 0x86
  1328.         jz      @f
  1329.         cmp     dl, 0x87
  1330.         jz      @f
  1331.         cmp     dl, 0xBC
  1332.         jz      @f
  1333.         cmp     dl, 0xBD
  1334.         jz      @f
  1335.         test    dl, 2
  1336.         jz      .d0
  1337.  
  1338.     @@:
  1339.         call    disasm_write_reg
  1340.         mov     ax, ', '
  1341.         stosw
  1342.         call    disasm_readrmop
  1343.         and     byte [edi], 0
  1344.         ret
  1345.  
  1346.     .d0:
  1347.         push    eax
  1348.         call    disasm_readrmop
  1349.         mov     ax, ', '
  1350.         stosw
  1351.         pop     eax
  1352.         call    disasm_write_reg
  1353.         and     byte [edi], 0
  1354.         ret
  1355.  
  1356. ;-----------------------------------------------------------------------------
  1357.  
  1358. cbound:
  1359.         mov     edx, eax
  1360.         mov     eax, 'boun'
  1361.         stosd
  1362.         mov     eax, 'd   '
  1363.         or      ch, 0xC0
  1364.         jmp     cop22.d1
  1365.  
  1366. ;-----------------------------------------------------------------------------
  1367.  
  1368. cop23:
  1369.         disasm_set_modew
  1370.         xchg    eax, edx
  1371.         call    disasm_get_byte
  1372.         dec     [disasm_cur_pos]
  1373.         shr     eax, 3
  1374.         and     eax, 7
  1375.         mov     eax, [disasm_op2cmds+eax*4]
  1376.  
  1377. ctest:
  1378.         stosd
  1379.         mov     eax, '    '
  1380.         stosd
  1381.         call    disasm_readrmop
  1382.         mov     ax, ', '
  1383.         stosw
  1384.         test    ch, 80h
  1385.         jz      .i8
  1386.         cmp     dl, 83h
  1387.         jz      .i8
  1388.         test    ch, 1
  1389.         jnz     .i16
  1390.         call    disasm_get_dword
  1391.         jmp     .ic
  1392.  
  1393.     .i8:
  1394.         xor     eax, eax
  1395.         call    disasm_get_byte
  1396.         cmp     dl, 83h
  1397.         jnz     .ic
  1398.         movsx   eax, al
  1399.         jmp     .ic
  1400.  
  1401.     .i16:
  1402.         xor     eax, eax
  1403.         call    disasm_get_word
  1404.  
  1405.     .ic:
  1406.         call    disasm_write_num
  1407.         and     byte [edi], 0
  1408.         ret
  1409.  
  1410. ;-----------------------------------------------------------------------------
  1411.  
  1412. cmovcc:
  1413.         or      ch, 0C0h
  1414.         and     eax, 0xF
  1415.         mov     ax, [disasm_jcc_codes + eax*2]
  1416.         mov     dword [edi], 'cmov'
  1417.         add     edi, 4
  1418.         stosw
  1419.         mov     ax, '  '
  1420.         stosw
  1421.         call    disasm_get_byte
  1422.         dec     [disasm_cur_pos]
  1423.         shr     eax, 3
  1424.         and     eax, 7
  1425.         call    disasm_write_reg1632
  1426.         mov     ax, ', '
  1427.         stosw
  1428.         call    disasm_readrmop
  1429.         and     byte [edi], 0
  1430.         ret
  1431.  
  1432. ; btx r/m,i8 = 0F BA
  1433. cbtx1:
  1434.         or      ch, 80h
  1435.         call    disasm_get_byte
  1436.         dec     [disasm_cur_pos]
  1437.         shr     al, 3
  1438.         and     eax, 7
  1439.         cmp     al, 4
  1440.         jb      cunk
  1441.         mov     eax, [btx1codes+eax*4-4*4]
  1442.         stosd
  1443.         mov     eax, '    '
  1444.         stosd
  1445.         call    disasm_readrmop
  1446.         mov     ax, ', '
  1447.         stosw
  1448.         jmp     disasm_i8u
  1449.  
  1450. ;-----------------------------------------------------------------------------
  1451.  
  1452. iglobal
  1453. btx1codes       dd      'bt  ','bts ','btr ','btc '
  1454. endg
  1455.  
  1456. ;-----------------------------------------------------------------------------
  1457.  
  1458. ; btx r/m,r = 0F 101xx011 (A3,AB,B3,BB)
  1459. cbtx2:
  1460.         shr     al, 3
  1461.         and     eax, 3
  1462.         mov     eax, [btx1codes+eax*4]
  1463.         stosd
  1464.         mov     eax, '    '
  1465.         stosd
  1466.         or      ch, 0xC0
  1467.         call    disasm_get_byte
  1468.         dec     [disasm_cur_pos]
  1469.         shr     al, 3
  1470.         and     eax, 7
  1471.         push    eax
  1472.         call    disasm_readrmop
  1473.         mov     ax, ', '
  1474.         stosw
  1475.         pop     eax
  1476.         call    disasm_write_reg1632
  1477.         and     byte [edi], 0
  1478.         ret
  1479.  
  1480. ;-----------------------------------------------------------------------------
  1481.  
  1482. csetcc:
  1483.         and     eax, 0xF
  1484.         mov     ax, [disasm_jcc_codes + eax*2]
  1485.         mov     dword [edi], 'setc'
  1486.         add     edi, 3
  1487.         stosw
  1488.         mov     ax, '  '
  1489.         stosw
  1490.         stosb
  1491.         call    disasm_readrmop
  1492.         and     byte [edi], 0
  1493.         ret
  1494.  
  1495. ;-----------------------------------------------------------------------------
  1496.  
  1497. iglobal
  1498. disasm_jcc_codes dw 'o ','no','b ','ae','z ','nz','be','a ','s ','ns','p ','np','l ','ge','le','g '
  1499. endg
  1500.  
  1501. ;-----------------------------------------------------------------------------
  1502.  
  1503. cjcc1:
  1504. cjmp2:
  1505.         cmp     al, 0xEB
  1506.         jz      .1
  1507.         and     eax, 0xF
  1508.         mov     ax, [disasm_jcc_codes + eax*2]
  1509.         jmp     .2
  1510.  
  1511.     .1:
  1512.         mov     ax, 'mp'
  1513.  
  1514.     .2:
  1515.         mov     byte [edi], 'j'
  1516.         inc     edi
  1517.         stosw
  1518.         mov     eax, '    '
  1519.         stosb
  1520.         stosd
  1521.         call    disasm_get_byte
  1522.         movsx   eax, al
  1523.  
  1524. disasm_rva:
  1525.         add     eax, [disasm_cur_pos]
  1526.         call    disasm_write_num
  1527.         and     byte [edi], 0
  1528.         ret
  1529.  
  1530. ;-----------------------------------------------------------------------------
  1531.  
  1532. ccall1:
  1533. cjmp1:
  1534. cjcc2:
  1535.         mov     edx, 'call'
  1536.         cmp     al, 0xE8
  1537.         jz      @f
  1538.         mov     edx, 'jmp '
  1539.         cmp     al, 0xE9
  1540.         jz      @f
  1541.         mov     edx, '    '
  1542.         and     eax, 0xF
  1543.         mov     dx, [disasm_jcc_codes+eax*2]
  1544.         shl     edx, 8
  1545.         mov     dl, 'j'
  1546.  
  1547.     @@:
  1548.         xchg    eax, edx
  1549.         stosd
  1550.         mov     eax, '    '
  1551.         stosd
  1552.         test    ch, 1
  1553.         jnz     @f
  1554.         call    disasm_get_dword
  1555.         jmp     disasm_rva
  1556.  
  1557.     @@:
  1558.         call    disasm_get_word
  1559.         add     eax, [disasm_cur_pos]
  1560.         and     eax, 0xFFFF
  1561.         call    disasm_write_num
  1562.         and     byte [edi], 0
  1563.         ret
  1564.  
  1565. ;-----------------------------------------------------------------------------
  1566.  
  1567. ccallf:
  1568.         mov     eax, 'call'
  1569.         stosd
  1570.         mov     eax, '    '
  1571.         stosd
  1572.         mov     al, 'd'
  1573.         test    ch, 1
  1574.         jnz     @f
  1575.         mov     al, 'p'
  1576.  
  1577.     @@:
  1578.         stosb
  1579.         mov     eax, 'word'
  1580.         stosd
  1581.         mov     al, ' '
  1582.         stosb
  1583.         test    ch, 1
  1584.         jnz     .1
  1585.         call    disasm_get_dword
  1586.         jmp     .2
  1587.  
  1588.     .1:
  1589.         xor     eax, eax
  1590.         call    disasm_get_word
  1591.  
  1592.     .2:
  1593.         push    eax
  1594.         xor     eax, eax
  1595.         call    disasm_get_word
  1596.         call    disasm_write_num
  1597.         mov     al, ':'
  1598.         stosb
  1599.         pop     eax
  1600.         call    disasm_write_num
  1601.         and     byte [edi], 0
  1602.         ret
  1603.  
  1604. ;-----------------------------------------------------------------------------
  1605.  
  1606. iglobal
  1607. op11codes       dd      'test',0,'not ','neg ','mul ','imul','div ','idiv'
  1608. op12codes       dd      'inc ','dec ','call',0,'jmp ',0,'push',0
  1609. endg
  1610.  
  1611. ;-----------------------------------------------------------------------------
  1612.  
  1613. cop1:
  1614.         disasm_set_modew
  1615.         xchg    eax, edx
  1616.         call    disasm_get_byte
  1617.         movzx   esi, al
  1618.         dec     [disasm_cur_pos]
  1619.         shr     al, 3
  1620.         and     eax, 7
  1621.         cmp     dl, 0xFE
  1622.         jnz     @f
  1623.         cmp     al, 1
  1624.         jbe     @f
  1625.  
  1626.     .0:
  1627.         inc     [disasm_cur_pos]
  1628.         jmp     cunk
  1629.  
  1630.     @@:
  1631.         and     edx, 8
  1632.         add     eax, edx
  1633.         cmp     al, 11
  1634.         jz      .callfar
  1635.         cmp     al, 13
  1636.         jz      .jmpfar
  1637.         mov     eax, [op11codes+eax*4]
  1638.         test    eax, eax
  1639.         jz      .0
  1640.         cmp     eax, 'test'
  1641.         jz      ctest
  1642.  
  1643.     .2:
  1644.         stosd
  1645.         mov     eax, '    '
  1646.         stosd
  1647.         call    disasm_readrmop
  1648.         and     byte [edi], 0
  1649.         ret
  1650.  
  1651.     .callfar:
  1652.         mov     eax, 'call'
  1653.  
  1654.     .1:
  1655.         cmp     esi, 0xC0
  1656.         jae     .0
  1657.         stosd
  1658.         mov     eax, '    '
  1659.         stosd
  1660.         mov     eax, 'far '
  1661.         stosd
  1662.         mov     al, 'd'
  1663.         test    ch, 1
  1664.         jnz     @f
  1665.         mov     al, 'p'
  1666.  
  1667.     @@:
  1668.         stosb
  1669.         or      ch, 1
  1670.         call    disasm_readrmop
  1671.         and     byte [edi], 0
  1672.         ret
  1673.  
  1674.     .jmpfar:
  1675.         mov     eax, 'jmp '
  1676.         jmp     .1
  1677.  
  1678. ;-----------------------------------------------------------------------------
  1679.  
  1680. cpop2:
  1681.         or      ch, 80h
  1682.         call    disasm_get_byte
  1683.         dec     [disasm_cur_pos]
  1684.         test    al, 00111000b
  1685.         jnz     cunk
  1686.         mov     eax, 'pop '
  1687.         jmp     cop1.2
  1688.  
  1689. ;-----------------------------------------------------------------------------
  1690.  
  1691. cloopnz:
  1692.         mov     eax, 'loop'
  1693.         stosd
  1694.         mov     eax, 'nz  '
  1695.         test    ch, 2
  1696.         jz      @f
  1697.         mov     ah, 'w'
  1698.  
  1699.     @@:
  1700.         jmp     cloop.cmn
  1701.  
  1702. cloopz:
  1703.         mov     eax, 'loop'
  1704.         stosd
  1705.         mov     eax, 'z   '
  1706.         test    ch, 2
  1707.         jz      @f
  1708.         mov     eax, 'zw  '
  1709.  
  1710.     @@:
  1711.         jmp     cloop.cmn
  1712.  
  1713. cjcxz:
  1714. cloop:
  1715.         cmp     al, 0xE2
  1716.         jz      .loop
  1717.         test    ch, 2
  1718.         jnz     .jcxz
  1719.         mov     eax, 'jecx'
  1720.         stosd
  1721.         mov     eax, 'z   '
  1722.         jmp     .cmn
  1723.  
  1724.     .jcxz:
  1725.         mov     eax, 'jcxz'
  1726.         stosd
  1727.         mov     eax, '    '
  1728.         jmp     .cmn
  1729.  
  1730.     .loop:
  1731.         mov     eax, 'loop'
  1732.         stosd
  1733.         mov     eax, '    '
  1734.         test    ch, 2
  1735.         jz      .cmn
  1736.         mov     al, 'w'
  1737.  
  1738.     .cmn:
  1739.         stosd
  1740.         call    disasm_get_byte
  1741.         movsx   eax, al
  1742.         add     eax, [disasm_cur_pos]
  1743.         test    ch, 1
  1744.         jz      @f
  1745.         and     eax, 0xFFFF
  1746.  
  1747. ;    @@:
  1748. disasm_write_num_done:
  1749.     @@:
  1750.         call    disasm_write_num
  1751.         and     byte [edi], 0
  1752.         ret
  1753.  
  1754. ;-----------------------------------------------------------------------------
  1755.  
  1756. ; imul r,r/m,i
  1757. cimul1:
  1758.         or      ch, 80h         ; 32bit operation
  1759.         xchg    eax, edx
  1760.         mov     eax, 'imul'
  1761.         stosd
  1762.         mov     eax, '    '
  1763.         stosd
  1764.         call    disasm_get_byte
  1765.         dec     [disasm_cur_pos]
  1766.         shr     al, 3
  1767.         and     eax, 7
  1768.         call    disasm_write_reg1632
  1769.         mov     ax, ', '
  1770.         stosw
  1771.         call    disasm_readrmop
  1772.         mov     ax, ', '
  1773.         stosw
  1774.         test    ch, 1
  1775.         jnz     .16
  1776.         cmp     dl, 0x69
  1777.         jz      .op32
  1778.         call    disasm_get_byte
  1779.         movsx   eax, al
  1780.         jmp     disasm_write_num_done
  1781.  
  1782.     .op32:
  1783.         call    disasm_get_dword
  1784.         jmp     disasm_write_num_done
  1785.  
  1786.     .16:
  1787.         cmp     dl, 0x69
  1788.         jz      .op16
  1789.         call    disasm_get_byte
  1790.         cbw
  1791.         jmp     disasm_write_num_done
  1792.  
  1793.     .op16:
  1794.         xor     eax, eax
  1795.         call    disasm_get_word
  1796.         jmp     disasm_write_num_done
  1797.  
  1798. ;-----------------------------------------------------------------------------
  1799.  
  1800. cshld:
  1801. cshrd:
  1802.         mov     edx, 'shld'
  1803.         test    al, 8
  1804.         jz      @f
  1805.         mov     edx, 'shrd'
  1806.  
  1807.     @@:
  1808.         xchg    eax, edx
  1809.         stosd
  1810.         mov     eax, '    '
  1811.         stosd
  1812.         call    disasm_get_byte
  1813.         dec     [disasm_cur_pos]
  1814.         shr     al, 3
  1815.         and     eax, 7
  1816.         push    eax
  1817.         or      ch, 80h
  1818.         call    disasm_readrmop
  1819.         mov     ax, ', '
  1820.         stosw
  1821.         pop     eax
  1822.         call    disasm_write_reg1632
  1823.         mov     ax, ', '
  1824.         stosw
  1825.         test    dl, 1
  1826.         jz      disasm_i8u
  1827.         mov     ax, 'cl'
  1828.         stosw
  1829.         and     byte [edi], 0
  1830.         ret
  1831.  
  1832. ;-----------------------------------------------------------------------------
  1833.  
  1834. ccbw:
  1835.         mov     eax, 'cbw '
  1836.         test    ch, 1
  1837.         jnz     @f
  1838.         mov     eax, 'cwde'
  1839.  
  1840.     @@:
  1841.         stosd
  1842.         and     byte [edi], 0
  1843.         ret
  1844.  
  1845. ccwd:
  1846.         mov     eax, 'cwd '
  1847.         test    ch, 1
  1848.         jnz     @b
  1849.         mov     eax, 'cdq '
  1850.         jmp     @b
  1851.  
  1852. ;-----------------------------------------------------------------------------
  1853.  
  1854. ccmpxchg8b:
  1855.         call    disasm_get_byte
  1856.         cmp     al, 0xC0
  1857.         jae     cerr
  1858.         shr     al, 3
  1859.         and     al, 7
  1860.         cmp     al, 1
  1861.         jnz     cerr
  1862.         dec     [disasm_cur_pos]
  1863.         mov     eax, 'cmpx'
  1864.         stosd
  1865.         mov     eax, 'chg8'
  1866.         stosd
  1867.         mov     al, 'b'
  1868.         stosb
  1869.         mov     al, ' '
  1870.         stosb
  1871.         or      ch, 40h
  1872.         call    disasm_readrmop
  1873.         and     byte [edi], 0
  1874.         ret
  1875.  
  1876. ;-----------------------------------------------------------------------------
  1877.  
  1878. iglobal
  1879. fpuD8   dd      'add ','mul ','com ','comp','sub ','subr','div ','divr'
  1880. endg
  1881.  
  1882. ;-----------------------------------------------------------------------------
  1883.  
  1884. cD8:
  1885.         call    disasm_get_byte
  1886.         dec     [disasm_cur_pos]
  1887.         push    eax
  1888.         shr     al, 3
  1889.         and     eax, 7
  1890.         mov     byte [edi], 'f'
  1891.         inc     edi
  1892.         xchg    eax, edx
  1893.         mov     eax, [fpuD8+edx*4]
  1894.         stosd
  1895.         mov     ax, '  '
  1896.         stosw
  1897.         stosb
  1898.         pop     eax
  1899.         cmp     dl, 2
  1900.         jb      .1
  1901.         cmp     dl, 3
  1902.         jbe     .2
  1903.  
  1904.     .1:
  1905.         cmp     al, 0xC0
  1906.         jb      .2
  1907.         mov     eax, 'st0,'
  1908.         stosd
  1909.         mov     al, ' '
  1910.         stosb
  1911.  
  1912.     .2:
  1913.         or      ch, 80h or 20h
  1914.         and     ch, not 1
  1915.         call    disasm_readrmop
  1916.         and     byte [edi], 0
  1917.         ret
  1918.  
  1919. ;-----------------------------------------------------------------------------
  1920.  
  1921. iglobal
  1922. fpuD9_2:
  1923.         dq      'fchs    ','fabs    ',0,0,'ftst    ','fxam    ',0,0
  1924.         db      'fld1    fldl2t  fldl2e  fldpi   fldlg2  fldln2  fldz    '
  1925.         dq      0
  1926.         db      'f2xm1   fyl2x   fptan   fpatan  fxtract fprem1  fdecstp fincstp '
  1927.         db      'fprem   fyl2xp1 fsqrt   fsincos frndint fscale  fsin    fcos    '
  1928. fpuD9_fnop      db      'fnop    '
  1929. endg
  1930.  
  1931. ;-----------------------------------------------------------------------------
  1932.  
  1933. cD9:
  1934.         call    disasm_get_byte
  1935.         sub     al, 0xC0
  1936.         jae     .l1
  1937.         dec     [disasm_cur_pos]
  1938.         shr     al, 3
  1939.         and     eax, 7
  1940.         cmp     al, 7
  1941.         jnz     @f
  1942.         mov     eax, 'fnst'
  1943.         stosd
  1944.         mov     eax, 'cw  '
  1945.         jmp     .x1
  1946.  
  1947.     @@:
  1948.         cmp     al, 5
  1949.         jnz     @f
  1950.         mov     eax, 'fldc'
  1951.         stosd
  1952.         mov     eax, 'w   '
  1953.  
  1954.     .x1:
  1955.         stosd
  1956.         or      ch, 0C1h
  1957.         jmp     .cmn
  1958.  
  1959.     @@:
  1960.         mov     edx, 'fld '
  1961.         test    al, al
  1962.         jz      @f
  1963.         mov     edx, 'fst '
  1964.         cmp     al, 2
  1965.         jz      @f
  1966.         mov     edx, 'fstp'
  1967.         cmp     al, 3
  1968.         jnz     cunk
  1969.  
  1970.     @@:
  1971.         xchg    eax, edx
  1972.         stosd
  1973.         mov     eax, '    '
  1974.         stosd
  1975.         or      ch, 80h
  1976.         and     ch, not 1
  1977.  
  1978.     .cmn:
  1979.         call    disasm_readrmop
  1980.         and     byte [edi], 0
  1981.         ret
  1982.  
  1983.     .l1:
  1984.         cmp     al, 10h
  1985.         jae     .l2
  1986.         mov     edx, 'fld '
  1987.         cmp     al, 8
  1988.         jb      @f
  1989.         mov     edx, 'fxch'
  1990.  
  1991.     @@:
  1992.         xchg    eax, edx
  1993.         stosd
  1994.         mov     eax, '    '
  1995.         stosd
  1996.         xchg    eax, edx
  1997.         and     al, 7
  1998.         add     al, '0'
  1999.         shl     eax, 16
  2000.         mov     ax, 'st'
  2001.         stosd
  2002.         clc
  2003.         ret
  2004.  
  2005.     .l2:
  2006.         cmp     al, 0x10
  2007.         jnz     @f
  2008.         mov     esi, fpuD9_fnop
  2009.         jmp     .l3
  2010.  
  2011.     @@:
  2012.         sub     al, 0x20
  2013.         jb      cerr
  2014.         lea     esi, [fpuD9_2+eax*8]
  2015.         cmp     byte [esi], 0
  2016.         jz      cerr
  2017.  
  2018.     .l3:
  2019.         movsd
  2020.         movsd
  2021.         and     byte [edi-1], 0
  2022.         ret
  2023.  
  2024. ;-----------------------------------------------------------------------------
  2025.  
  2026. cDA:
  2027.         call    disasm_get_byte
  2028.         cmp     al, 0xC0
  2029.         jae     cunk
  2030.         dec     [disasm_cur_pos]
  2031.         shr     al, 3
  2032.         and     eax, 7
  2033.         mov     word [edi], 'fi'
  2034.         inc     edi
  2035.         inc     edi
  2036.         mov     eax, [fpuD8+eax*4]
  2037.         stosd
  2038.         mov     ax, '  '
  2039.         stosw
  2040.         or      ch, 80h
  2041.         and     ch, not 1       ; 32-bit operand
  2042.         call    disasm_readrmop
  2043.         and     byte [edi], 0
  2044.         ret
  2045.  
  2046. ;-----------------------------------------------------------------------------
  2047.  
  2048. iglobal
  2049. fpuDB   dd      'ild ',0,'ist ','istp',0,'ld  ',0,'stp '
  2050. endg
  2051.  
  2052. ;-----------------------------------------------------------------------------
  2053.  
  2054. cDB:
  2055.         call    disasm_get_byte
  2056.         cmp     al, 0xC0
  2057.         jae     .1
  2058.         dec     [disasm_cur_pos]
  2059.         shr     al, 3
  2060.         and     eax, 7
  2061.         xchg    eax, edx
  2062.         mov     eax, [fpuDB+edx*4]
  2063.         test    eax, eax
  2064.         jz      cerr
  2065.         mov     byte [edi], 'f'
  2066.         inc     edi
  2067.         stosd
  2068.         mov     ax, '  '
  2069.         stosw
  2070.         stosb
  2071.         or      ch, 80h
  2072.         and     ch, not 1       ; 32-bit operand
  2073.         cmp     dl, 4
  2074.         jb      @f
  2075.         or      ch, 20h
  2076.         and     ch, not 80h     ; 80-bit operand
  2077.  
  2078.     @@:
  2079.         call    disasm_readrmop
  2080.         and     byte [edi], 0
  2081.         ret
  2082.  
  2083.     .1:
  2084.         cmp     al, 0xE3
  2085.         jnz     cunk
  2086.         mov     eax, 'fnin'
  2087.         stosd
  2088.         mov     eax, 'it'
  2089.         stosd
  2090.         dec     edi
  2091.         ret             ; CF cleared
  2092.  
  2093. ;-----------------------------------------------------------------------------
  2094.  
  2095. iglobal
  2096. fpuDC   dd      'add ','mul ',0,0,'subr','sub ','divr','div '
  2097. endg
  2098.  
  2099. ;-----------------------------------------------------------------------------
  2100.  
  2101. cDC:
  2102.         call    disasm_get_byte
  2103.         cmp     al, 0xC0
  2104.         jae     .1
  2105.         dec     [disasm_cur_pos]
  2106.         shr     al, 3
  2107.         and     eax, 7
  2108.         mov     byte [edi], 'f'
  2109.         inc     edi
  2110.         mov     eax, [fpuD8+eax*4]
  2111.         stosd
  2112.         mov     ax, '  '
  2113.         stosw
  2114.         stosb
  2115.         or      ch, 0A1h        ; qword
  2116.         call    disasm_readrmop
  2117.         and     byte [edi], 0
  2118.         ret
  2119.  
  2120.     .1:
  2121.         mov     dl, al
  2122.         shr     al, 3
  2123.         and     eax, 7
  2124.         mov     eax, [fpuDC+eax*4]
  2125.         test    eax, eax
  2126.         jz      cerr
  2127.         mov     byte [edi], 'f'
  2128.         inc     edi
  2129.         stosd
  2130.         mov     eax, '   s'
  2131.         stosd
  2132.         mov     al, 't'
  2133.         stosb
  2134.         and     edx, 7
  2135.         lea     eax, [edx+'0']
  2136.         stosb
  2137.         mov     eax, ', st'
  2138.         stosd
  2139.         mov     ax, '0'
  2140.         stosw
  2141.         ret     ; CF cleared
  2142.  
  2143. ;-----------------------------------------------------------------------------
  2144.  
  2145. iglobal
  2146. fpuDD   dd      'fld ',0,'fst ','fstp',0,0,0,0
  2147. fpuDD_2 dq      'ffree   ',0,'fst     ','fstp    ','fucom   ','fucomp  ',0,0
  2148. endg
  2149.  
  2150. ;-----------------------------------------------------------------------------
  2151.  
  2152. cDD:
  2153.         call    disasm_get_byte
  2154.         cmp     al, 0xC0
  2155.         jae     .1
  2156.         dec     [disasm_cur_pos]
  2157.         shr     al, 3
  2158.         and     eax, 7
  2159.         xchg    eax, edx
  2160.         mov     eax, [fpuDD+edx*4]
  2161.         test    eax, eax
  2162.         jz      cunk
  2163.         stosd
  2164.         mov     eax, '    '
  2165.         stosd
  2166.         or      ch, 0A1h        ; qword operand
  2167.         call    disasm_readrmop
  2168.         and     byte [edi], 0
  2169.         ret
  2170.  
  2171.     .1:
  2172.         push    eax
  2173.         shr     al, 3
  2174.         and     eax, 7
  2175.         xchg    eax, edx
  2176.         mov     eax, dword [fpuDD_2+edx*8]
  2177.         test    eax, eax
  2178.         jz      cerr
  2179.         stosd
  2180.         mov     eax, dword [fpuDD_2+4+edx*8]
  2181.         stosd
  2182.         mov     ax, 'st'
  2183.         stosw
  2184.         pop     eax
  2185.         and     al, 7
  2186.         add     al, '0'
  2187.         stosb
  2188.         and     byte [edi], 0
  2189.         ret
  2190.  
  2191. ;-----------------------------------------------------------------------------
  2192.  
  2193. iglobal
  2194. fpuDE   dd      'add ','mul ',0,0,'subr','sub ','divr','div '
  2195. endg
  2196.  
  2197. ;-----------------------------------------------------------------------------
  2198.  
  2199. cDE:
  2200.         call    disasm_get_byte
  2201.         cmp     al, 0xC0
  2202.         jae     .1
  2203.         dec     [disasm_cur_pos]
  2204.         mov     word [edi], 'fi'
  2205.         inc     edi
  2206.         inc     edi
  2207.         shr     al, 3
  2208.         and     eax, 7
  2209.         mov     eax, [fpuD8+eax*4]
  2210.         stosd
  2211.         mov     ax, '  '
  2212.         stosw
  2213.         or      ch, 81h         ; force 16-bit
  2214.         call    disasm_readrmop
  2215.         and     byte [edi], 0
  2216.         ret
  2217.  
  2218.     .1:
  2219.         push    eax
  2220.         shr     al, 3
  2221.         and     eax, 7
  2222.         xchg    eax, edx
  2223.         mov     eax, [fpuDE+edx*4]
  2224.         test    eax, eax
  2225.         jz      .fcompp
  2226.         mov     byte [edi], 'f'
  2227.         inc     edi
  2228.         stosd
  2229.         mov     al, 'p'
  2230.         cmp     byte [edi-1], ' '
  2231.         jnz     @f
  2232.         mov     byte [edi-1], al
  2233.         mov     al, ' '
  2234.  
  2235.     @@:
  2236.         stosb
  2237.         mov     eax, '  st'
  2238.         stosd
  2239.         pop     eax
  2240.         and     al, 7
  2241.         add     al, '0'
  2242.         stosb
  2243.         mov     ax, ', '
  2244.         stosw
  2245.         mov     eax, 'st0'
  2246.         stosd
  2247.         ret     ; CF cleared
  2248.  
  2249.     .fcompp:
  2250.         pop     eax
  2251.         cmp     al, 0xD9
  2252.         jnz     cerr
  2253.         mov     eax, 'fcom'
  2254.         stosd
  2255.         mov     ax, 'pp'
  2256.         stosw
  2257.         and     byte [edi], 0
  2258.         ret
  2259.  
  2260. ;-----------------------------------------------------------------------------
  2261.  
  2262. iglobal
  2263. fpuDF   dd      'ild ',0,'ist ','istp','bld ','ild ','bstp','istp'
  2264. endg
  2265.  
  2266. ;-----------------------------------------------------------------------------
  2267.  
  2268. cDF:
  2269.         call    disasm_get_byte
  2270.         cmp     al, 0xC0
  2271.         jae     .1
  2272.         dec     [disasm_cur_pos]
  2273.         shr     al, 3
  2274.         and     eax, 7
  2275.         xchg    eax, edx
  2276.         mov     eax, [fpuDF+edx*4]
  2277.         test    eax, eax
  2278.         jz      cerr
  2279.         mov     byte [edi], 'f'
  2280.         inc     edi
  2281.         stosd
  2282.         mov     ax, '  '
  2283.         stosw
  2284.         stosb
  2285.         or      ch, 81h         ; force 16-bit operand
  2286.         cmp     dl, 4
  2287.         jb      @f
  2288.         or      ch, 20h
  2289.         test    dl, 1
  2290.         jnz     @f
  2291.         or      ch, 40h
  2292.  
  2293.     @@:
  2294.         call    disasm_readrmop
  2295.         and     byte [edi], 0
  2296.         ret
  2297.  
  2298.     .1:
  2299.         cmp     al, 0xE0
  2300.         jnz     cunk
  2301.         mov     eax, 'fnst'
  2302.         stosd
  2303.         mov     eax, 'sw  '
  2304.         stosd
  2305.         mov     ax, 'ax'
  2306.         stosw
  2307.         and     byte [edi], 0
  2308.         ret
  2309.  
  2310. ;-----------------------------------------------------------------------------
  2311.  
  2312. cmovd1:
  2313.         mov     eax, 'movd'
  2314.         stosd
  2315.         mov     eax, '    '
  2316.         stosd
  2317.         call    disasm_get_byte
  2318.         dec     [disasm_cur_pos]
  2319.         shr     al, 3
  2320.         and     eax, 7
  2321.         call    disasm_write_mmreg
  2322.         mov     ax, ', '
  2323.         stosw
  2324.         or      ch, 0C0h
  2325.         and     ch, not 1
  2326.         call    disasm_readrmop
  2327.         and     byte [edi], 0
  2328.         ret
  2329.  
  2330. ;-----------------------------------------------------------------------------
  2331.  
  2332. cmovd2:
  2333.         mov     eax, 'movd'
  2334.         stosd
  2335.         mov     eax, '    '
  2336.         stosd
  2337.         call    disasm_get_byte
  2338.         dec     [disasm_cur_pos]
  2339.         shr     al, 3
  2340.         and     eax, 7
  2341.         push    eax ecx
  2342.         or      ch, 0C0h
  2343.         and     ch, not 1
  2344.         call    disasm_readrmop
  2345.         mov     ax, ', '
  2346.         stosw
  2347.         pop     ecx eax
  2348.         call    disasm_write_mmreg
  2349.         and     byte [edi], 0
  2350.         ret
  2351.  
  2352. ;-----------------------------------------------------------------------------
  2353.  
  2354. cmovq1:
  2355.         test    ch, 1
  2356.         jz      .mm
  2357.         mov     eax, 'movd'
  2358.         stosd
  2359.         mov     eax, 'qa  '
  2360.         stosd
  2361.         jmp     disasm_mmx1
  2362.  
  2363.     .mm:
  2364.         mov     eax, 'movq'
  2365.         stosd
  2366.         mov     eax, '    '
  2367.         stosd
  2368.         jmp     disasm_mmx1
  2369.  
  2370. ;-----------------------------------------------------------------------------
  2371.  
  2372. cmovq2:
  2373.         test    ch, 1
  2374.         jz      .mm
  2375.         mov     eax, 'movd'
  2376.         stosd
  2377.         mov     eax, 'qa  '
  2378.         stosd
  2379.         jmp     disasm_mmx3
  2380.  
  2381.     .mm:
  2382.         mov     eax, 'movq'
  2383.  
  2384. disasm_mmx2:
  2385.         stosd
  2386.         mov     eax, '    '
  2387.         stosd
  2388.  
  2389. disasm_mmx3:
  2390.         or      ch, 50h
  2391.         call    disasm_get_byte
  2392.         dec     [disasm_cur_pos]
  2393.         push    eax
  2394.         call    disasm_readrmop
  2395.         mov     ax, ', '
  2396.         stosw
  2397.         pop     eax
  2398.         shr     al, 3
  2399.         and     eax, 7
  2400.         call    disasm_write_mmreg
  2401.         and     byte [edi], 0
  2402.         ret
  2403.  
  2404. ;-----------------------------------------------------------------------------
  2405.  
  2406. iglobal
  2407. mmx_cmds:
  2408.         db      0x60,'unpcklbw'
  2409.         db      0x61,'unpcklwd'
  2410.         db      0x62,'unpckldq'
  2411.         db      0x63,'packsswb'
  2412.         db      0x64,'pcmpgtb '
  2413.         db      0x65,'pcmpgtw '
  2414.         db      0x66,'pcmpgtd '
  2415.         db      0x67,'packuswb'
  2416.         db      0x68,'unpckhbw'
  2417.         db      0x69,'unpckhwd'
  2418.         db      0x6A,'unpckhdq'
  2419.         db      0x6B,'packssdw'
  2420.         db      0x74,'pcmpeqb '
  2421.         db      0x75,'pcmpeqw '
  2422.         db      0x76,'pcmpeqd '
  2423.         db      0xD4,'paddq   '
  2424.         db      0xD5,'pmullw  '
  2425.         db      0xD8,'psubusb '
  2426.         db      0xD9,'psubusw '
  2427.         db      0xDA,'pminub  '
  2428.         db      0xDB,'pand    '
  2429.         db      0xDC,'paddusb '
  2430.         db      0xDD,'paddusw '
  2431.         db      0xDE,'pmaxub  '
  2432.         db      0xDF,'pandn   '
  2433.         db      0xE0,'pavgb   '
  2434.         db      0xE3,'pavgw   '
  2435.         db      0xE4,'pmulhuw '
  2436.         db      0xE5,'pmulhw  '
  2437.         db      0xE8,'psubsb  '
  2438.         db      0xE9,'psubsw  '
  2439.         db      0xEA,'pminsw  '
  2440.         db      0xEB,'por     '
  2441.         db      0xEC,'paddsb  '
  2442.         db      0xED,'paddsw  '
  2443.         db      0xEE,'pmaxsw  '
  2444.         db      0xEF,'pxor    '
  2445.         db      0xF4,'pmuludq '
  2446.         db      0xF5,'pmaddwd '
  2447.         db      0xF6,'psadbw  '
  2448.         db      0xF8,'psubb   '
  2449.         db      0xF9,'psubw   '
  2450.         db      0xFA,'psubd   '
  2451.         db      0xFB,'psubq   '
  2452.         db      0xFC,'paddb   '
  2453.         db      0xFD,'paddw   '
  2454.         db      0xFE,'paddd   '
  2455. endg
  2456.  
  2457. ;-----------------------------------------------------------------------------
  2458.  
  2459. cpcmn:
  2460.         mov     esi, mmx_cmds
  2461.  
  2462.     @@:
  2463.         cmp     al, [esi]
  2464.         jz      @f
  2465.         add     esi, 9
  2466.         jmp     @b
  2467.  
  2468.     @@:
  2469.         inc     esi
  2470.         mov     al, 'p'
  2471.         cmp     byte [esi], al
  2472.         jz      @f
  2473.         stosb
  2474.  
  2475.     @@:
  2476.         movsd
  2477.         movsd
  2478.         cmp     byte [edi-1], ' '
  2479.         jz      @f
  2480.         mov     al, ' '
  2481.         stosb
  2482.  
  2483. ;    @@:
  2484.  
  2485. disasm_mmx1:
  2486.     @@:
  2487.         or      ch, 50h
  2488.         call    disasm_get_byte
  2489.         dec     [disasm_cur_pos]
  2490.         shr     al, 3
  2491.         and     eax, 7
  2492.         call    disasm_write_mmreg
  2493.         mov     ax, ', '
  2494.         stosw
  2495.         call    disasm_readrmop
  2496.         cmp     word [disasm_string], 'cm'
  2497.         jz      .cmp
  2498.         and     byte [edi], 0
  2499.         ret
  2500.  
  2501.     .cmp:
  2502.         call    disasm_get_byte
  2503.         and     eax, 7
  2504.         mov     dx, 'eq'
  2505.         dec     eax
  2506.         js      @f
  2507.         mov     dx, 'lt'
  2508.         jz      @f
  2509.         mov     dh, 'e'
  2510.         dec     eax
  2511.         jnz     .no2
  2512.  
  2513.     @@:
  2514.         xchg    dx, word [disasm_string+3]
  2515.         mov     word [disasm_string+5], dx
  2516.         and     byte [edi], 0
  2517.         ret
  2518.  
  2519.     .no2:
  2520.         dec     eax
  2521.         jnz     @f
  2522.         add     edi, 2
  2523.         push    edi
  2524.         lea     esi, [edi-3]
  2525.         lea     ecx, [esi-(disasm_string+8)+2]
  2526.         std
  2527.         rep movsb
  2528.         cld
  2529.         mov     cx, word [esi-3]
  2530.         mov     dword [esi-3], 'unor'
  2531.         mov     byte [esi+1], 'd'
  2532.         mov     word [esi+2], cx
  2533.         pop     edi
  2534.         and     byte [edi+1], 0
  2535.         ret
  2536.  
  2537.     @@:
  2538.         mov     edx, 'neq'
  2539.         dec     eax
  2540.         jz      @f
  2541.         mov     edx, 'nlt'
  2542.         dec     eax
  2543.         jz      @f
  2544.         mov     edx, 'nle'
  2545.         dec     eax
  2546.         jz      @f
  2547.         mov     edx, 'ord'
  2548.  
  2549.     @@:
  2550.         push    edi
  2551.         lea     esi, [edi-1]
  2552.         lea     ecx, [esi-(disasm_string+8)+2]
  2553.         std
  2554.         rep movsb
  2555.         cld
  2556.         mov     cx, word [esi-3]
  2557.         mov     dword [esi-3], edx
  2558.         mov     word [esi], cx
  2559.         pop     edi
  2560.         and     byte [edi+1], 0
  2561.         ret
  2562.  
  2563. ;-----------------------------------------------------------------------------
  2564.  
  2565. cpsrlw:
  2566.         mov     eax, 'psrl'
  2567.         jmp     @f
  2568.  
  2569. cpsraw:
  2570.         mov     eax, 'psra'
  2571.         jmp     @f
  2572.  
  2573. cpsllw:
  2574.         mov     eax, 'psll'
  2575.  
  2576.     @@:
  2577.         stosd
  2578.         mov     eax, 'w   '
  2579.         stosd
  2580.         jmp     disasm_mmx1
  2581.  
  2582. cpsrld:
  2583.         mov     eax, 'psrl'
  2584.         jmp     @f
  2585.  
  2586. cpsrad:
  2587.         mov     eax, 'psra'
  2588.         jmp     @f
  2589.  
  2590. cpslld:
  2591.         mov     eax, 'psll'
  2592.  
  2593.     @@:
  2594.         stosd
  2595.         mov     eax, 'd   '
  2596.         stosd
  2597.         jmp     disasm_mmx1
  2598.  
  2599. cpsrlq:
  2600.         mov     eax, 'psrl'
  2601.         jmp     @f
  2602.  
  2603. cpsllq:
  2604.         mov     eax, 'psll'
  2605.  
  2606.     @@:
  2607.         stosd
  2608.         mov     eax, 'q   '
  2609.         stosd
  2610.         jmp     disasm_mmx1
  2611.  
  2612. ;-----------------------------------------------------------------------------
  2613.  
  2614. csse1:
  2615. iglobal
  2616. sse_cmds1:
  2617.         db      0x2F,4,'comi'
  2618.         db      0x54,3,'and'
  2619.         db      0x55,4,'andn'
  2620.         db      0x58,3,'add'
  2621.         db      0xC2,3,'cmp'
  2622. endg
  2623.         mov     esi, sse_cmds1+1
  2624.  
  2625.     .1:
  2626.     @@:
  2627.         movzx   edx, byte [esi]
  2628.         cmp     al, [esi-1]
  2629.         jz      @f
  2630.         lea     esi, [esi+edx+2]
  2631.         jmp     @b
  2632.  
  2633.     @@:
  2634.         push    ecx
  2635.         mov     ecx, edx
  2636.         inc     esi
  2637.         rep movsb
  2638.         pop     ecx
  2639.         mov     al, 's'
  2640.         cmp     byte [edi-1], 'i'
  2641.         jz      @f
  2642.         mov     al, 'p'
  2643.  
  2644.     @@:
  2645.         stosb
  2646.         mov     al, 'd'
  2647.         test    ch, 1
  2648.         jnz     @f
  2649.         mov     al, 's'
  2650.  
  2651.     @@:
  2652.         stosb
  2653.         push    ecx
  2654.         push    5
  2655.         pop     ecx
  2656.         sub     ecx, edx
  2657.         adc     ecx, 1
  2658.         mov     al, ' '
  2659.         rep stosb
  2660.         pop     ecx
  2661.         or      ch, 1           ; force XMM reg
  2662.         jmp     disasm_mmx1
  2663.  
  2664. ;-----------------------------------------------------------------------------
  2665.  
  2666. csse2:
  2667. iglobal
  2668. sse_cmds2:
  2669.         db      0xD0,6,'addsub'
  2670.         db      0,0
  2671. endg
  2672.         test    ch, 1
  2673.         jz      cerr
  2674.         mov     esi, sse_cmds2+1
  2675.         jmp     csse1.1
  2676.  
  2677. cpshift:
  2678.         mov     dl, al
  2679.         mov     ax, 'ps'
  2680.         stosw
  2681.         call    disasm_get_byte
  2682.         push    eax
  2683.         and     al, 0xC0
  2684.         cmp     al, 0xC0
  2685.         jnz     .pop_cunk
  2686.         pop     eax
  2687.         push    eax
  2688.         shr     al, 3
  2689.         and     eax, 7
  2690.         cmp     al, 2
  2691.         jz      .rl
  2692.         cmp     al, 4
  2693.         jz      .ra
  2694.         cmp     al, 6
  2695.         jz      .ll
  2696.  
  2697.     .pop_cunk:
  2698.         pop     eax
  2699.         jmp     cunk
  2700.  
  2701.     .ll:
  2702.         mov     ax, 'll'
  2703.         jmp     @f
  2704.  
  2705.     .rl:
  2706.         mov     ax, 'rl'
  2707.         jmp     @f
  2708.  
  2709.     .ra:
  2710.         cmp     dl, 0x73
  2711.         jz      .pop_cunk
  2712.         mov     ax, 'ra'
  2713.  
  2714.     @@:
  2715.         stosw
  2716.         mov     al, 'w'
  2717.         cmp     dl, 0x71
  2718.         jz      @f
  2719.         mov     al, 'd'
  2720.         cmp     dl, 0x72
  2721.         jz      @f
  2722.         mov     al, 'q'
  2723.  
  2724.     @@:
  2725.         stosb
  2726.         mov     ax, '  '
  2727.         stosw
  2728.         stosb
  2729.         pop     eax
  2730.         and     eax, 7
  2731.         call    disasm_write_mmreg
  2732.         mov     ax, ', '
  2733.         stosw
  2734.         xor     eax, eax
  2735.         call    disasm_get_byte
  2736.         call    disasm_write_num
  2737.         and     byte [edi], 0
  2738.         ret
  2739.  
  2740. ;-----------------------------------------------------------------------------
  2741.  
  2742. iglobal
  2743. grp15c1 dq      'fxsave  ','fxrstor ','ldmxcsr ','stmxcsr ',0,0,0,'clflush '
  2744. endg
  2745.  
  2746. ;-----------------------------------------------------------------------------
  2747.  
  2748. cgrp15:
  2749.         call    disasm_get_byte
  2750.         cmp     al, 0xC0
  2751.         jae     cunk
  2752.         shr     al, 3
  2753.         and     eax, 7
  2754.         mov     edx, eax
  2755.         mov     eax, dword [grp15c1+eax*8]
  2756.         test    eax, eax
  2757.         jz      cerr
  2758.         dec     [disasm_cur_pos]
  2759.         stosd
  2760.         mov     eax, dword [grp15c1+4+edx*8]
  2761.         stosd
  2762.         or      ch, 40h
  2763.         call    disasm_readrmop
  2764.         and     byte [edi], 0
  2765.         ret
  2766.  
  2767. ; vim: ft=fasm tabstop=4
  2768.  
  2769.