Subversion Repositories Kolibri OS

Rev

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