Subversion Repositories Kolibri OS

Compare Revisions

Regard whitespace Rev 3674 → Rev 3675

/programs/develop/mtdbg/README
0,0 → 1,38
Description
===========
 
Kolibri debugger - simple user mode debugger
 
TODO
====
 
See inline 'TODO' comments
Also long term goals:
 
1. Commands history and navigation
2. Command autocompletion
3. Save memory block into file
4. Gdb remote protocol support (gdb-stub)
5. Live assembly
6. Improve disassembly engine
7. Split out context handling and kernel interface
8. Split out commands handler and tables in cmd.inc
8. Restrurize and refactor data section
9. Add disassembler listing export into file
10. Record trace log
11. Improve FPU/MMX/SSE/AVX debugging
12. Document disassembly engine deeply
13. Add tips for insufficient code sequences
 
 
Hacking
=======
 
If you want improve or change some features see files description:
 
1. mtdbg.asm - Main loop, events handling, data container
2. gui.inc - GUI implementation
3. disasm.inc - Disassembler engine
4. disasm_tbl.inc - Instruction tables for disassembler engine
5. parser.inc - Parser and evaluator of expressions
 
/programs/develop/mtdbg/cmd.inc
0,0 → 1,101
; TODO: add both visual and command modes
 
; scan and build command line
scan_cmdline:
pusha
cmp [cmdline_len], cmdline_width
jae waitevent
push eax
call clear_cmdline_end
pop eax
mov edi, cmdline
mov ecx, [cmdline_len]
add edi, ecx
lea esi, [edi-1]
sub ecx, [cmdline_pos]
std
rep movsb
cld
stosb
inc [cmdline_len]
call draw_cmdline_end
inc [cmdline_pos]
call draw_cursor
jmp waitevent
.backspace:
cmp [cmdline_pos], 0
jz waitevent
dec [cmdline_pos]
.delchar:
call clear_cmdline_end
mov edi, [cmdline_pos]
dec [cmdline_len]
mov ecx, [cmdline_len]
sub ecx, edi
add edi, cmdline
lea esi, [edi+1]
rep movsb
call draw_cmdline_end
call draw_cursor
jmp waitevent
.del:
mov eax, [cmdline_pos]
cmp eax, [cmdline_len]
jae waitevent
jmp .delchar
.left:
cmp [cmdline_pos], 0
jz waitevent
call hide_cursor
dec [cmdline_pos]
call draw_cursor
jmp waitevent
.right:
mov eax, [cmdline_pos]
cmp eax, [cmdline_len]
jae waitevent
call hide_cursor
inc [cmdline_pos]
call draw_cursor
jmp waitevent
.home:
call hide_cursor
and [cmdline_pos], 0
call draw_cursor
jmp waitevent
.end:
call hide_cursor
mov eax, [cmdline_len]
mov [cmdline_pos], eax
call draw_cursor
.up:
.down:
jmp waitevent
;; We also trying to execute previous command, if empty command_line
.enter:
mov ecx, [cmdline_len]
cmp ecx, 0
jg .exec_cur
mov cl, byte [cmdline_prev]
cmp cl, 0
jz waitevent
.exec_prev:
mov esi, cmdline_prev
jmp .exec
.exec_cur:
mov esi, cmdline
.exec:
mov byte [esi+ecx], 0
and [cmdline_pos], 0
push esi
call clear_cmdline_end
call draw_cursor
pop esi
and [cmdline_len], 0
; skip leading spaces
call skip_spaces
cmp al, 0
jz waitevent
 
; vim: ft= fasm
 
/programs/develop/mtdbg/disasm.inc
0,0 → 1,2768
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; DISASSEMBLER ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
; TODO: prepare to work independently from debugger
 
;-----------------------------------------------------------------------------
; Read next byte for disassembly
;
; out: AL = byte
disasm_get_byte:
push ecx
mov ecx, [disasm_cur_pos]
sub ecx, [disasm_start_pos]
cmp ecx, [disasm_buf_size]
jae disasm_err
mov al, [disasm_buffer+ecx]
pop ecx
inc [disasm_cur_pos]
ret
 
;-----------------------------------------------------------------------------
; Read next word for disassembly
;
; out: AX = word
disasm_get_word:
push ecx
mov ecx, [disasm_cur_pos]
sub ecx, [disasm_start_pos]
inc ecx
cmp ecx, [disasm_buf_size]
jae disasm_err
mov ax, word [disasm_buffer-1+ecx]
pop ecx
add [disasm_cur_pos], 2
ret
 
;-----------------------------------------------------------------------------
; Read next dword for disassembly
;
; out: EAX = dword
disasm_get_dword:
push ecx
mov ecx, [disasm_cur_pos]
sub ecx, [disasm_start_pos]
add ecx, 3
cmp ecx, [disasm_buf_size]
jae disasm_err
mov eax, dword [disasm_buffer-3+ecx]
pop ecx
add [disasm_cur_pos], 4
ret
 
;-----------------------------------------------------------------------------
 
disasm_err:
mov esp, ebp
 
; TODO: make it local?
stc_ret:
stc
ret
 
;-----------------------------------------------------------------------------
; Exit from disassembly loop
 
disasm_ret:
mov esp, ebp
and byte [edi], 0
ret
 
;-----------------------------------------------------------------------------
; Disassembly one instruction
;
; Read data, in loop, to read multibyte instruction opcodes
 
disasm_instr:
mov ebp, esp
cmp [debuggee_pid], 0
jz stc_ret
mov edi, disasm_string
xor ecx, ecx
 
; TODO: make it local?
; ecx=flags (IN or OUT?)
disasm_loop1:
xor eax, eax
call disasm_get_byte
jmp dword [disasm_table_1 + eax*4]
 
;-----------------------------------------------------------------------------
 
cop0:
clock:
csegcs:
csegds:
cseges:
csegss:
csegfs:
cseggs:
mov esi, cmd1
 
iglobal
cmd1:
db 0x2E,3,'cs:'
db 0x36,3,'ss:'
db 0x3E,3,'ds:'
db 0x26,3,'es:'
db 0x64,3,'fs:'
db 0x65,3,'gs:'
db 0x06,10,'push es'
db 0x07,10,'pop es'
db 0x0E,10,'push cs'
db 0x16,10,'push ss'
db 0x17,10,'pop ss'
db 0x1E,10,'push ds'
db 0x1F,10,'pop ds'
db 0x27,3,'daa'
db 0x2F,3,'das'
db 0x37,3,'aaa'
db 0x3F,3,'aas'
db 0x60,6,0,'pusha'
db 0x61,5,0,'popa'
db 0x90,3,'nop'
db 0x9B,5,'fwait'
db 0x9C,6,0,'pushf'
db 0x9D,5,0,'popf'
db 0x9E,4,'sahf'
db 0x9F,4,'lahf'
db 0xA4,5,'movsb'
db 0xA5,5,0,'movs'
db 0xA6,5,'cmpsb'
db 0xA7,5,0,'cmps'
db 0xAA,5,'stosb'
db 0xAB,5,0,'stos'
db 0xAC,5,'lodsb'
db 0xAD,5,0,'lods'
db 0xAE,5,'scasb'
db 0xAF,5,0,'scas'
db 0xC3,3,'ret'
db 0xC9,5,'leave'
db 0xCC,4,'int3'
db 0xF0,4,'lock'
db 0xF5,3,'cmc'
db 0xF8,3,'clc'
db 0xF9,3,'stc'
db 0xFA,3,'cli'
db 0xFB,3,'sti'
db 0xFC,3,'cld'
db 0xFD,3,'std'
 
cmd2:
db 0x05,7,'syscall'
db 0x06,4,'clts'
db 0x31,5,'rdtsc'
db 0x34,8,'sysenter'
db 0xA2,5,'cpuid'
db 0x77,4,'emms'
 
endg
jmp @f
 
;-----------------------------------------------------------------------------
 
ccpuid:
crdtsc:
cemms:
cop0_F:
mov esi, cmd2
 
@@:
cmp al, [esi]
jz .found
inc esi
movzx edx, byte [esi]
inc esi
add esi, edx
jmp @b
 
.found:
inc esi
lodsb
cmp byte [esi], 0
jz @f
movzx ecx, al
 
disasm_1:
rep movsb
and byte [edi], 0
ret
 
@@:
mov dl, ch
movzx ecx, al
dec ecx
inc esi
rep movsb
test dl, 1
mov al, 'w'
jnz @f
mov al, 'd'
 
@@:
stosb
and byte [edi], 0
ret
 
c67:
or ch, 2
jmp disasm_loop1
 
c66:
or ch, 1
jmp disasm_loop1
 
;-----------------------------------------------------------------------------
 
cxlat:
cunk:
cerr:
mov eax, '???'
stosd
clc
ret
 
cF:
call disasm_get_byte
jmp dword [disasm_table_2 + eax*4]
 
;-----------------------------------------------------------------------------
; Parse operand prefixes
 
crep:
push [disasm_cur_pos]
call disasm_get_byte
cmp al, 0x0F
jz .sse
mov dl, al
mov eax, 'rep '
stosd
mov al, dl
 
@@:
and eax, not 1
cmp al, 0x66
jnz @f
call disasm_get_byte
mov dl, al
jmp @b
 
@@:
cmp al, 0xA6
jz .repz
cmp al, 0xAE
jz .repz
cmp al, 0xA4
jz .prefix
cmp al, 0xAA
jz .prefix
cmp al, 0xAC
jz .prefix
cmp al, 0x6C
jz .prefix
cmp al, 0x6E
jz .prefix
 
.noprefix:
pop [disasm_cur_pos]
and byte [edi-1], 0
ret
 
.repz:
mov byte [edi-1], 'z'
mov al, ' '
stosb
 
.prefix:
pop [disasm_cur_pos]
jmp disasm_loop1
 
.sse:
pop eax
call disasm_get_byte
 
;-----------------------------------------------------------------------------
 
iglobal
rep_sse_cmds:
db 0x58,3,'add'
db 0xC2,3,'cmp'
db 0,0
endg
mov esi, rep_sse_cmds+1
 
@@:
movzx edx, byte [esi]
cmp al, [esi-1]
jz @f
lea esi, [esi+edx+2]
cmp byte [esi], 0
jnz @b
sub [disasm_cur_pos], 2
mov eax, 'rep'
stosd
ret
 
@@:
push ecx
mov ecx, edx
inc esi
rep movsb
pop ecx
mov al, 's'
stosb
jmp rep_sse_final
 
;-----------------------------------------------------------------------------
 
crepnz:
call disasm_get_byte
cmp al, 0x0F
jz .sse
mov dl, al
mov eax, 'repn'
stosd
mov al, 'z'
stosb
mov al, ' '
stosb
movzx eax, dl
cmp al, 0x6C
jb crep.noprefix
cmp al, 0x6F
jbe .prefix
cmp al, 0xA4
jb crep.noprefix
cmp al, 0xA7
jbe .prefix
cmp al, 0xAA
jb crep.noprefix
cmp al, 0xAF
ja crep.noprefix
 
.prefix:
jmp cop0
 
.sse:
call disasm_get_byte
mov esi, rep_sse_cmds+1
 
@@:
movzx edx, byte [esi]
cmp al, [esi-1]
jz .found0
lea esi, [esi+edx+2]
cmp byte [esi], 0
jnz @b
mov esi, sse_cmds2+1
 
@@:
movzx edx, byte [esi]
cmp al, [esi-1]
jz .found1
lea esi, [esi+edx+2]
cmp byte [esi], 0
jnz @b
sub [disasm_cur_pos], 2
mov eax, 'repn'
stosd
mov al, 'z'
stosb
and byte [edi], 0
ret
 
.found0:
push ecx
mov ecx, edx
inc esi
rep movsb
pop ecx
mov al, 's'
stosb
mov al, 'd'
jmp rep_sse_final
 
.found1:
push ecx
mov ecx, edx
inc esi
rep movsb
pop ecx
mov al, 'p'
stosb
mov al, 's'
 
rep_sse_final:
stosb
push ecx
push 5
pop ecx
sub ecx, edx
adc ecx, 1
mov al, ' '
rep stosb
pop ecx
or ch, 1
jmp disasm_mmx1
 
;-----------------------------------------------------------------------------
 
macro disasm_set_modew
{
test al, 1
jz @f
or ch, 80h
@@:
}
 
;-----------------------------------------------------------------------------
 
cmov2:
disasm_set_modew
; mov r/m,i
call disasm_get_byte
dec [disasm_cur_pos]
test al, 00111000b
jnz cunk
mov eax, 'mov '
stosd
mov eax, ' '
stosd
call disasm_readrmop
mov ax, ', '
stosw
xor eax, eax
test ch, 80h
jnz .1
call disasm_get_byte
jmp .3
 
.1:
test ch, 1
jnz .2
call disasm_get_dword
jmp .3
 
.2:
call disasm_get_word
 
.3:
call disasm_write_num
and byte [edi], 0
ret
 
;-----------------------------------------------------------------------------
 
cret2:
mov eax, 'ret '
stosd
mov eax, ' '
stosd
xor eax, eax
jmp cmov2.2
 
;-----------------------------------------------------------------------------
 
disasm_write_num:
push esi
cmp eax, 0x80
jl .nosymb
lea esi, [eax-1]
test eax, esi
jz .nosymb
call find_symbol
jc .nosymb
 
@@:
lodsb
test al, al
jz @f
stosb
jmp @b
 
@@:
pop esi
ret
 
.nosymb:
pop esi
push ecx eax
inc edi
 
@@:
mov ecx, eax
shr eax, 4
jz @f
inc edi
jmp @b
 
@@:
pop eax
cmp ecx, 10
jb @f
inc edi
 
@@:
push edi eax
 
@@:
mov ecx, eax
and al, 0xF
cmp al, 10
sbb al, 69h
das
dec edi
mov [edi], al
mov eax, ecx
shr eax, 4
jnz @b
cmp ecx, 10
jb @f
mov byte [edi-1], '0'
 
@@:
pop eax edi ecx
cmp eax, 10
jb @f
mov byte [edi], 'h'
inc edi
 
@@:
ret
 
;-----------------------------------------------------------------------------
 
iglobal
label disasm_regs32 dword
label disasm_regs dword
db 'eax',0
db 'ecx',0
db 'edx',0
db 'ebx',0
db 'esp',0
db 'ebp',0
db 'esi',0
db 'edi',0
 
disasm_regs16 dw 'ax','cx','dx','bx','sp','bp','si','di'
disasm_regs8 dw 'al','cl','dl','bl','ah','ch','dh','bh'
disasm_scale db '1248'
endg
 
;-----------------------------------------------------------------------------
 
disasm_readrmop:
call disasm_get_byte
test ch, 40h
jnz .skip_size
push eax
and al, 0xC0
cmp al, 0xC0
pop eax
jz .skip_size
test ch, 80h
jz .byte
test ch, 1
jnz .word
mov dword [edi], 'dwor'
mov byte [edi+4], 'd'
inc edi
jmp @f
 
.byte:
test ch, 20h
jz .qb
mov byte [edi], 't'
inc edi
 
.qb:
mov dword [edi], 'byte'
jmp @f
 
.word:
test ch, 20h
jz .qw
mov byte [edi], 'q'
inc edi
 
.qw:
mov dword [edi], 'word'
 
@@:
mov byte [edi+4], ' '
add edi, 5
 
.skip_size:
test ch, 2
jnz disasm_readrmop16
push ecx
movzx ecx, al
and eax, 7
shr ecx, 6
jz .vmod0
jp .vmod3
mov byte [edi], '['
inc edi
cmp al, 4
jz .sib1
mov eax, [disasm_regs+eax*4]
stosd
dec edi
jmp @f
 
.sib1:
call .parse_sib
 
@@:
mov al, '+'
stosb
dec ecx
jz .vmod1
call disasm_get_dword
jmp @f
 
.vmod1:
call disasm_get_byte
movsx eax, al
 
@@:
test eax, eax
jns .2
neg eax
mov byte [edi-1], '-'
 
.2:
call disasm_write_num
 
.2a:
mov al, ']'
stosb
pop ecx
ret
 
.vmod3:
pop ecx
test ch, 10h
jnz .vmod3_mmi
test ch, 80h
jz .vmod3_byte
test ch, 1
jnz .vmod3_word
test ch, 20h
jnz .vmod3_sti
mov eax, [disasm_regs32+eax*4]
stosd
dec edi
ret
 
.vmod3_byte:
mov ax, [disasm_regs8+eax*2]
 
@@:
stosw
ret
 
.vmod3_word:
mov ax, [disasm_regs16+eax*2]
jmp @b
 
.vmod3_sti:
mov word [edi], 'st'
add al, '0'
mov byte [edi+2], al
add edi, 3
ret
 
.vmod3_mmi:
disasm_write_mmreg = $
 
test ch, 1
jz @f
mov byte [edi], 'x'
inc edi
 
@@:
mov word [edi], 'mm'
add al, '0'
mov byte [edi+2], al
add edi, 3
ret
 
.vmod0:
mov byte [edi], '['
inc edi
cmp al, 4
jz .sib2
cmp al, 5
jz .ofs32
mov eax, [disasm_regs+eax*4]
stosd
mov byte [edi-1], ']'
pop ecx
ret
 
.ofs32:
call disasm_get_dword
jmp .2
 
.sib2:
call .parse_sib
mov al, ']'
stosb
pop ecx
ret
 
.parse_sib:
call disasm_get_byte
push edx
mov dl, al
mov dh, 0
and eax, 7
cmp al, 5
jnz @f
jecxz .sib0
 
@@:
mov eax, [disasm_regs+eax*4]
stosd
dec edi
mov dh, 1
 
.sib0:
mov al, dl
shr eax, 3
and eax, 7
cmp al, 4
jz .sibret
test dh, dh
jz @f
mov byte [edi], '+'
inc edi
 
@@:
mov eax, [disasm_regs+eax*4]
stosd
dec edi
shr dl, 6
jz @f
mov al, '*'
stosb
movzx eax, dl
mov al, [disasm_scale+eax]
stosb
 
@@:
.sibret:
test dh, dh
jnz .sibret2
call disasm_get_dword
cmp byte [edi-1], '['
jz @f
mov byte [edi], '+'
test eax, eax
jns .sibns
neg eax
mov byte [edi], '-'
 
.sibns:
inc edi
 
@@:
call disasm_write_num
 
.sibret2:
pop edx
ret
 
;-----------------------------------------------------------------------------
 
iglobal
disasm_rm16_1 dd 'bxsi','bxdi','bpsi','bpdi'
disasm_rm16_2 dw 'si','di','bp','bx'
endg
 
;-----------------------------------------------------------------------------
 
disasm_readrmop16:
push ecx
movzx ecx, al
and eax, 7
shr ecx, 6
jz .vmod0
jp disasm_readrmop.vmod3 ; mod=3 is the same in 16- and 32-bit code
; 1 or 2
mov byte [edi], '['
inc edi
cmp al, 4
jae @f
mov eax, [disasm_rm16_1+eax*4]
stosw
mov al, '+'
stosb
shr eax, 16
jmp .1
 
@@:
mov eax, dword [disasm_rm16_2+eax*2-4*2]
 
.1:
stosw
mov al, '+'
stosb
xor eax, eax
dec ecx
jnz .2
call disasm_get_byte
cbw
jmp @f
 
.2:
call disasm_get_word
 
@@:
test ax, ax
jns @f
mov byte [edi-1], '-'
neg ax
 
@@:
call disasm_write_num
 
.done1:
mov al, ']'
stosb
pop ecx
ret
 
.vmod0:
mov byte [edi], '['
inc edi
cmp al, 6
jz .ofs16
cmp al, 4
jae @f
mov eax, [disasm_rm16_1+eax*4]
stosw
mov al, '+'
stosb
shr eax, 16
jmp .3
 
@@:
mov eax, dword [disasm_rm16_2+eax*2-4*2]
 
.3:
stosw
jmp .done1
 
.ofs16:
xor eax, eax
call disasm_get_word
call disasm_write_num
jmp .done1
 
;-----------------------------------------------------------------------------
 
cpush21:
mov eax, 'push'
stosd
mov eax, ' '
stosd
 
disasm_i32:
call disasm_get_dword
call disasm_write_num
and byte [edi], 0
ret
 
cpush22:
mov eax, 'push'
stosd
mov eax, ' '
stosd
call disasm_get_byte
movsx eax, al
 
@@:
call disasm_write_num
and byte [edi], 0
ret
 
;-----------------------------------------------------------------------------
 
center:
mov eax, 'ente'
stosd
mov eax, 'r '
stosd
xor eax, eax
call disasm_get_word
call disasm_write_num
mov al, ','
stosb
mov al, ' '
stosb
xor eax, eax
call disasm_get_byte
jmp @b
 
;-----------------------------------------------------------------------------
 
cinc1:
; inc reg32
cdec1:
; dec reg32
cpush1:
; push reg32
cpop1:
; pop reg32
cbswap:
; bswap reg32
mov edx, eax
and edx, 7
shr eax, 3
sub al, 8
mov esi, 'inc '
jz @f
mov esi, 'dec '
dec al
jz @f
mov esi, 'push'
dec al
jz @f
mov esi, 'pop '
dec al
jz @f
mov esi, 'bswa'
 
@@:
xchg eax, esi
stosd
mov eax, ' '
jz @f
mov al, 'p'
 
@@:
stosd
xchg eax, edx
call disasm_write_reg1632
and byte [edi], 0
ret
 
;-----------------------------------------------------------------------------
 
cxchg1:
; xchg eax,reg32
and eax, 7
xchg eax, edx
mov eax, 'xchg'
stosd
mov eax, ' '
stosd
xor eax, eax
call disasm_write_reg1632
mov ax, ', '
stosw
xchg eax, edx
call disasm_write_reg1632
and byte [edi], 0
ret
 
cint:
mov eax, 'int '
stosd
mov eax, ' '
stosd
 
disasm_i8u:
xor eax, eax
call disasm_get_byte
call disasm_write_num
and byte [edi], 0
ret
 
;-----------------------------------------------------------------------------
 
cmov11:
; mov r8,i8
mov ecx, eax
mov eax, 'mov '
stosd
mov eax, ' '
stosd
and ecx, 7
mov ax, [disasm_regs8+ecx*2]
stosw
mov ax, ', '
stosw
jmp disasm_i8u
 
;-----------------------------------------------------------------------------
 
cmov12:
; mov r32,i32
xchg eax, edx
mov eax, 'mov '
stosd
mov eax, ' '
stosd
xchg eax, edx
and eax, 7
call disasm_write_reg1632
mov ax, ', '
stosw
jmp cmov2.1
 
;-----------------------------------------------------------------------------
 
iglobal
disasm_shifts dd 'rol ','ror ','rcl ','rcr ','shl ','shr ','sal ','sar '
endg
 
;-----------------------------------------------------------------------------
 
cshift2:
; shift r/m,1 = D0/D1
cshift3:
; shift r/m,cl = D2/D3
disasm_set_modew
mov dl, al
call disasm_get_byte
dec [disasm_cur_pos]
shr al, 3
and eax, 7
mov eax, [disasm_shifts+eax*4]
stosd
mov eax, ' '
stosd
call disasm_readrmop
cmp dl, 0xD2
jb .s1
mov eax, ', cl'
stosd
and byte [edi], 0
ret
 
.s1:
mov eax, ', 1'
stosd
clc
ret
 
;-----------------------------------------------------------------------------
 
cshift1:
; shift r/m,i8 = C0/C1
disasm_set_modew
call disasm_get_byte
dec [disasm_cur_pos]
shr al, 3
and eax, 7
mov eax, [disasm_shifts+eax*4]
stosd
mov eax, ' '
stosd
call disasm_readrmop
mov ax, ', '
stosw
jmp disasm_i8u
 
;-----------------------------------------------------------------------------
 
caam:
mov eax, 'aam '
jmp @f
 
caad:
mov eax, 'aad '
 
@@:
stosd
mov eax, ' '
stosd
xor eax, eax
call disasm_get_byte
cmp al, 10
jz @f
call disasm_write_num
 
@@:
and byte [edi], 0
ret
 
;-----------------------------------------------------------------------------
 
cmov3:
; A0: mov al,[ofs32]
; A1: mov ax/eax,[ofs32]
; A2: mov [ofs32],al
; A3: mov [ofs32],ax/eax
mov edx, 'mov '
xchg eax, edx
stosd
mov eax, ' '
stosd
test dl, 2
jnz .1
call .write_acc
mov ax, ', '
stosw
call .write_ofs32
jmp .2
 
.1:
call .write_ofs32
mov ax, ', '
stosw
call .write_acc
 
.2:
and byte [edi], 0
ret
 
.write_acc:
test dl, 1
jz .8bit
test ch, 1
jnz .16bit
mov eax, 'eax'
stosd
dec edi
ret
 
.16bit:
mov ax, 'ax'
stosw
ret
 
.8bit:
mov ax, 'al'
stosw
ret
 
.write_ofs32:
mov al, '['
stosb
call disasm_get_dword
call disasm_write_num
mov al, ']'
stosb
ret
 
;-----------------------------------------------------------------------------
 
disasm_write_reg:
test ch, 80h
jnz disasm_write_reg1632
mov ax, [disasm_regs8+eax*2]
stosw
ret
 
;-----------------------------------------------------------------------------
 
disasm_write_reg1632:
test ch, 1
jnz @f
mov eax, [disasm_regs32+eax*4]
stosd
dec edi
ret
 
@@:
mov ax, [disasm_regs16+eax*2]
stosw
ret
 
;-----------------------------------------------------------------------------
 
; 0F B6/B7
cmovzx:
; 0F BE/BF
cmovsx:
mov edx, eax
disasm_set_modew
mov eax, 'movz'
cmp dl, 0xB8
jb @f
mov eax, 'movs'
 
@@:
stosd
mov eax, 'x '
stosd
call disasm_get_byte
dec [disasm_cur_pos]
shr al, 3
and eax, 7
call disasm_write_reg1632
mov ax, ', '
stosw
or ch, 1 ; 2nd operand - 8 or 16 bits
call disasm_readrmop
and byte [edi], 0
ret
 
;-----------------------------------------------------------------------------
 
iglobal
disasm_op2cmds dd 'add ','or ','adc ','sbb ','and ','sub ','xor ','cmp '
endg
 
;-----------------------------------------------------------------------------
 
cop21:
disasm_set_modew
mov esi, 'test'
cmp al, 0A8h
jae @f
shr al, 3
and eax, 7
mov esi, [disasm_op2cmds+eax*4]
 
@@:
xchg eax, esi
stosd
mov eax, ' '
stosd
test ch, 80h
jnz .1632
mov eax, 'al, '
stosd
jmp disasm_i8u
 
.1632:
test ch, 1
jnz .16
mov eax, 'eax,'
stosd
mov al, ' '
stosb
call disasm_get_dword
jmp .x
 
.16:
mov eax, 'ax, '
stosd
xor eax, eax
call disasm_get_word
 
.x:
call disasm_write_num
and byte [edi], 0
ret
 
;-----------------------------------------------------------------------------
 
carpl:
xor edx, edx
or ch, 0C1h
mov eax, 'arpl'
jmp cop22.d2
 
;-----------------------------------------------------------------------------
 
ccmpxchg:
xor edx, edx
disasm_set_modew
or ch, 40h
mov eax, 'cmpx'
stosd
mov eax, 'chg '
jmp cop22.d1
 
;-----------------------------------------------------------------------------
 
cbsf:
cbsr:
or ch, 80h
 
;-----------------------------------------------------------------------------
 
cop22:
disasm_set_modew
or ch, 40h
mov edx, eax
mov esi, 'lea '
cmp al, 8Dh
jz @f
mov esi, 'imul'
cmp al, 0xAF
jz @f
mov esi, 'bsf '
cmp al, 0BCh
jz @f
mov esi, 'bsr '
cmp al, 0BDh
jz @f
mov esi, 'mov '
cmp al, 88h
jae @f
mov esi, 'xchg'
cmp al, 86h
jae @f
mov esi, 'test'
cmp al, 84h
jae @f
shr al, 3
and eax, 7
mov esi, [disasm_op2cmds+eax*4]
 
@@:
xchg eax, esi
 
.d2:
stosd
mov eax, ' '
 
.d1:
stosd
call disasm_get_byte
dec [disasm_cur_pos]
shr al, 3
and eax, 7
cmp dl, 0x8D
jz @f
cmp dl, 0x86
jz @f
cmp dl, 0x87
jz @f
cmp dl, 0xBC
jz @f
cmp dl, 0xBD
jz @f
test dl, 2
jz .d0
 
@@:
call disasm_write_reg
mov ax, ', '
stosw
call disasm_readrmop
and byte [edi], 0
ret
 
.d0:
push eax
call disasm_readrmop
mov ax, ', '
stosw
pop eax
call disasm_write_reg
and byte [edi], 0
ret
 
;-----------------------------------------------------------------------------
 
cbound:
mov edx, eax
mov eax, 'boun'
stosd
mov eax, 'd '
or ch, 0xC0
jmp cop22.d1
 
;-----------------------------------------------------------------------------
 
cop23:
disasm_set_modew
xchg eax, edx
call disasm_get_byte
dec [disasm_cur_pos]
shr eax, 3
and eax, 7
mov eax, [disasm_op2cmds+eax*4]
 
ctest:
stosd
mov eax, ' '
stosd
call disasm_readrmop
mov ax, ', '
stosw
test ch, 80h
jz .i8
cmp dl, 83h
jz .i8
test ch, 1
jnz .i16
call disasm_get_dword
jmp .ic
 
.i8:
xor eax, eax
call disasm_get_byte
cmp dl, 83h
jnz .ic
movsx eax, al
jmp .ic
 
.i16:
xor eax, eax
call disasm_get_word
 
.ic:
call disasm_write_num
and byte [edi], 0
ret
 
;-----------------------------------------------------------------------------
 
cmovcc:
or ch, 0C0h
and eax, 0xF
mov ax, [disasm_jcc_codes + eax*2]
mov dword [edi], 'cmov'
add edi, 4
stosw
mov ax, ' '
stosw
call disasm_get_byte
dec [disasm_cur_pos]
shr eax, 3
and eax, 7
call disasm_write_reg1632
mov ax, ', '
stosw
call disasm_readrmop
and byte [edi], 0
ret
 
; btx r/m,i8 = 0F BA
cbtx1:
or ch, 80h
call disasm_get_byte
dec [disasm_cur_pos]
shr al, 3
and eax, 7
cmp al, 4
jb cunk
mov eax, [btx1codes+eax*4-4*4]
stosd
mov eax, ' '
stosd
call disasm_readrmop
mov ax, ', '
stosw
jmp disasm_i8u
 
;-----------------------------------------------------------------------------
 
iglobal
btx1codes dd 'bt ','bts ','btr ','btc '
endg
 
;-----------------------------------------------------------------------------
 
; btx r/m,r = 0F 101xx011 (A3,AB,B3,BB)
cbtx2:
shr al, 3
and eax, 3
mov eax, [btx1codes+eax*4]
stosd
mov eax, ' '
stosd
or ch, 0xC0
call disasm_get_byte
dec [disasm_cur_pos]
shr al, 3
and eax, 7
push eax
call disasm_readrmop
mov ax, ', '
stosw
pop eax
call disasm_write_reg1632
and byte [edi], 0
ret
 
;-----------------------------------------------------------------------------
 
csetcc:
and eax, 0xF
mov ax, [disasm_jcc_codes + eax*2]
mov dword [edi], 'setc'
add edi, 3
stosw
mov ax, ' '
stosw
stosb
call disasm_readrmop
and byte [edi], 0
ret
 
;-----------------------------------------------------------------------------
 
iglobal
disasm_jcc_codes dw 'o ','no','b ','ae','z ','nz','be','a ','s ','ns','p ','np','l ','ge','le','g '
endg
 
;-----------------------------------------------------------------------------
 
cjcc1:
cjmp2:
cmp al, 0xEB
jz .1
and eax, 0xF
mov ax, [disasm_jcc_codes + eax*2]
jmp .2
 
.1:
mov ax, 'mp'
 
.2:
mov byte [edi], 'j'
inc edi
stosw
mov eax, ' '
stosb
stosd
call disasm_get_byte
movsx eax, al
 
disasm_rva:
add eax, [disasm_cur_pos]
call disasm_write_num
and byte [edi], 0
ret
 
;-----------------------------------------------------------------------------
 
ccall1:
cjmp1:
cjcc2:
mov edx, 'call'
cmp al, 0xE8
jz @f
mov edx, 'jmp '
cmp al, 0xE9
jz @f
mov edx, ' '
and eax, 0xF
mov dx, [disasm_jcc_codes+eax*2]
shl edx, 8
mov dl, 'j'
 
@@:
xchg eax, edx
stosd
mov eax, ' '
stosd
test ch, 1
jnz @f
call disasm_get_dword
jmp disasm_rva
 
@@:
call disasm_get_word
add eax, [disasm_cur_pos]
and eax, 0xFFFF
call disasm_write_num
and byte [edi], 0
ret
 
;-----------------------------------------------------------------------------
 
ccallf:
mov eax, 'call'
stosd
mov eax, ' '
stosd
mov al, 'd'
test ch, 1
jnz @f
mov al, 'p'
 
@@:
stosb
mov eax, 'word'
stosd
mov al, ' '
stosb
test ch, 1
jnz .1
call disasm_get_dword
jmp .2
 
.1:
xor eax, eax
call disasm_get_word
 
.2:
push eax
xor eax, eax
call disasm_get_word
call disasm_write_num
mov al, ':'
stosb
pop eax
call disasm_write_num
and byte [edi], 0
ret
 
;-----------------------------------------------------------------------------
 
iglobal
op11codes dd 'test',0,'not ','neg ','mul ','imul','div ','idiv'
op12codes dd 'inc ','dec ','call',0,'jmp ',0,'push',0
endg
 
;-----------------------------------------------------------------------------
 
cop1:
disasm_set_modew
xchg eax, edx
call disasm_get_byte
movzx esi, al
dec [disasm_cur_pos]
shr al, 3
and eax, 7
cmp dl, 0xFE
jnz @f
cmp al, 1
jbe @f
 
.0:
inc [disasm_cur_pos]
jmp cunk
 
@@:
and edx, 8
add eax, edx
cmp al, 11
jz .callfar
cmp al, 13
jz .jmpfar
mov eax, [op11codes+eax*4]
test eax, eax
jz .0
cmp eax, 'test'
jz ctest
 
.2:
stosd
mov eax, ' '
stosd
call disasm_readrmop
and byte [edi], 0
ret
 
.callfar:
mov eax, 'call'
 
.1:
cmp esi, 0xC0
jae .0
stosd
mov eax, ' '
stosd
mov eax, 'far '
stosd
mov al, 'd'
test ch, 1
jnz @f
mov al, 'p'
 
@@:
stosb
or ch, 1
call disasm_readrmop
and byte [edi], 0
ret
 
.jmpfar:
mov eax, 'jmp '
jmp .1
 
;-----------------------------------------------------------------------------
 
cpop2:
or ch, 80h
call disasm_get_byte
dec [disasm_cur_pos]
test al, 00111000b
jnz cunk
mov eax, 'pop '
jmp cop1.2
 
;-----------------------------------------------------------------------------
 
cloopnz:
mov eax, 'loop'
stosd
mov eax, 'nz '
test ch, 2
jz @f
mov ah, 'w'
 
@@:
jmp cloop.cmn
 
cloopz:
mov eax, 'loop'
stosd
mov eax, 'z '
test ch, 2
jz @f
mov eax, 'zw '
 
@@:
jmp cloop.cmn
 
cjcxz:
cloop:
cmp al, 0xE2
jz .loop
test ch, 2
jnz .jcxz
mov eax, 'jecx'
stosd
mov eax, 'z '
jmp .cmn
 
.jcxz:
mov eax, 'jcxz'
stosd
mov eax, ' '
jmp .cmn
 
.loop:
mov eax, 'loop'
stosd
mov eax, ' '
test ch, 2
jz .cmn
mov al, 'w'
 
.cmn:
stosd
call disasm_get_byte
movsx eax, al
add eax, [disasm_cur_pos]
test ch, 1
jz @f
and eax, 0xFFFF
 
; @@:
disasm_write_num_done:
@@:
call disasm_write_num
and byte [edi], 0
ret
 
;-----------------------------------------------------------------------------
 
; imul r,r/m,i
cimul1:
or ch, 80h ; 32bit operation
xchg eax, edx
mov eax, 'imul'
stosd
mov eax, ' '
stosd
call disasm_get_byte
dec [disasm_cur_pos]
shr al, 3
and eax, 7
call disasm_write_reg1632
mov ax, ', '
stosw
call disasm_readrmop
mov ax, ', '
stosw
test ch, 1
jnz .16
cmp dl, 0x69
jz .op32
call disasm_get_byte
movsx eax, al
jmp disasm_write_num_done
 
.op32:
call disasm_get_dword
jmp disasm_write_num_done
 
.16:
cmp dl, 0x69
jz .op16
call disasm_get_byte
cbw
jmp disasm_write_num_done
 
.op16:
xor eax, eax
call disasm_get_word
jmp disasm_write_num_done
 
;-----------------------------------------------------------------------------
 
cshld:
cshrd:
mov edx, 'shld'
test al, 8
jz @f
mov edx, 'shrd'
 
@@:
xchg eax, edx
stosd
mov eax, ' '
stosd
call disasm_get_byte
dec [disasm_cur_pos]
shr al, 3
and eax, 7
push eax
or ch, 80h
call disasm_readrmop
mov ax, ', '
stosw
pop eax
call disasm_write_reg1632
mov ax, ', '
stosw
test dl, 1
jz disasm_i8u
mov ax, 'cl'
stosw
and byte [edi], 0
ret
 
;-----------------------------------------------------------------------------
 
ccbw:
mov eax, 'cbw '
test ch, 1
jnz @f
mov eax, 'cwde'
 
@@:
stosd
and byte [edi], 0
ret
 
ccwd:
mov eax, 'cwd '
test ch, 1
jnz @b
mov eax, 'cdq '
jmp @b
 
;-----------------------------------------------------------------------------
 
ccmpxchg8b:
call disasm_get_byte
cmp al, 0xC0
jae cerr
shr al, 3
and al, 7
cmp al, 1
jnz cerr
dec [disasm_cur_pos]
mov eax, 'cmpx'
stosd
mov eax, 'chg8'
stosd
mov al, 'b'
stosb
mov al, ' '
stosb
or ch, 40h
call disasm_readrmop
and byte [edi], 0
ret
 
;-----------------------------------------------------------------------------
 
iglobal
fpuD8 dd 'add ','mul ','com ','comp','sub ','subr','div ','divr'
endg
 
;-----------------------------------------------------------------------------
 
cD8:
call disasm_get_byte
dec [disasm_cur_pos]
push eax
shr al, 3
and eax, 7
mov byte [edi], 'f'
inc edi
xchg eax, edx
mov eax, [fpuD8+edx*4]
stosd
mov ax, ' '
stosw
stosb
pop eax
cmp dl, 2
jb .1
cmp dl, 3
jbe .2
 
.1:
cmp al, 0xC0
jb .2
mov eax, 'st0,'
stosd
mov al, ' '
stosb
 
.2:
or ch, 80h or 20h
and ch, not 1
call disasm_readrmop
and byte [edi], 0
ret
 
;-----------------------------------------------------------------------------
 
iglobal
fpuD9_2:
dq 'fchs ','fabs ',0,0,'ftst ','fxam ',0,0
db 'fld1 fldl2t fldl2e fldpi fldlg2 fldln2 fldz '
dq 0
db 'f2xm1 fyl2x fptan fpatan fxtract fprem1 fdecstp fincstp '
db 'fprem fyl2xp1 fsqrt fsincos frndint fscale fsin fcos '
fpuD9_fnop db 'fnop '
endg
 
;-----------------------------------------------------------------------------
 
cD9:
call disasm_get_byte
sub al, 0xC0
jae .l1
dec [disasm_cur_pos]
shr al, 3
and eax, 7
cmp al, 7
jnz @f
mov eax, 'fnst'
stosd
mov eax, 'cw '
jmp .x1
 
@@:
cmp al, 5
jnz @f
mov eax, 'fldc'
stosd
mov eax, 'w '
 
.x1:
stosd
or ch, 0C1h
jmp .cmn
 
@@:
mov edx, 'fld '
test al, al
jz @f
mov edx, 'fst '
cmp al, 2
jz @f
mov edx, 'fstp'
cmp al, 3
jnz cunk
 
@@:
xchg eax, edx
stosd
mov eax, ' '
stosd
or ch, 80h
and ch, not 1
 
.cmn:
call disasm_readrmop
and byte [edi], 0
ret
 
.l1:
cmp al, 10h
jae .l2
mov edx, 'fld '
cmp al, 8
jb @f
mov edx, 'fxch'
 
@@:
xchg eax, edx
stosd
mov eax, ' '
stosd
xchg eax, edx
and al, 7
add al, '0'
shl eax, 16
mov ax, 'st'
stosd
clc
ret
 
.l2:
cmp al, 0x10
jnz @f
mov esi, fpuD9_fnop
jmp .l3
 
@@:
sub al, 0x20
jb cerr
lea esi, [fpuD9_2+eax*8]
cmp byte [esi], 0
jz cerr
 
.l3:
movsd
movsd
and byte [edi-1], 0
ret
 
;-----------------------------------------------------------------------------
 
cDA:
call disasm_get_byte
cmp al, 0xC0
jae cunk
dec [disasm_cur_pos]
shr al, 3
and eax, 7
mov word [edi], 'fi'
inc edi
inc edi
mov eax, [fpuD8+eax*4]
stosd
mov ax, ' '
stosw
or ch, 80h
and ch, not 1 ; 32-bit operand
call disasm_readrmop
and byte [edi], 0
ret
 
;-----------------------------------------------------------------------------
 
iglobal
fpuDB dd 'ild ',0,'ist ','istp',0,'ld ',0,'stp '
endg
 
;-----------------------------------------------------------------------------
 
cDB:
call disasm_get_byte
cmp al, 0xC0
jae .1
dec [disasm_cur_pos]
shr al, 3
and eax, 7
xchg eax, edx
mov eax, [fpuDB+edx*4]
test eax, eax
jz cerr
mov byte [edi], 'f'
inc edi
stosd
mov ax, ' '
stosw
stosb
or ch, 80h
and ch, not 1 ; 32-bit operand
cmp dl, 4
jb @f
or ch, 20h
and ch, not 80h ; 80-bit operand
 
@@:
call disasm_readrmop
and byte [edi], 0
ret
 
.1:
cmp al, 0xE3
jnz cunk
mov eax, 'fnin'
stosd
mov eax, 'it'
stosd
dec edi
ret ; CF cleared
 
;-----------------------------------------------------------------------------
 
iglobal
fpuDC dd 'add ','mul ',0,0,'subr','sub ','divr','div '
endg
 
;-----------------------------------------------------------------------------
 
cDC:
call disasm_get_byte
cmp al, 0xC0
jae .1
dec [disasm_cur_pos]
shr al, 3
and eax, 7
mov byte [edi], 'f'
inc edi
mov eax, [fpuD8+eax*4]
stosd
mov ax, ' '
stosw
stosb
or ch, 0A1h ; qword
call disasm_readrmop
and byte [edi], 0
ret
 
.1:
mov dl, al
shr al, 3
and eax, 7
mov eax, [fpuDC+eax*4]
test eax, eax
jz cerr
mov byte [edi], 'f'
inc edi
stosd
mov eax, ' s'
stosd
mov al, 't'
stosb
and edx, 7
lea eax, [edx+'0']
stosb
mov eax, ', st'
stosd
mov ax, '0'
stosw
ret ; CF cleared
 
;-----------------------------------------------------------------------------
 
iglobal
fpuDD dd 'fld ',0,'fst ','fstp',0,0,0,0
fpuDD_2 dq 'ffree ',0,'fst ','fstp ','fucom ','fucomp ',0,0
endg
 
;-----------------------------------------------------------------------------
 
cDD:
call disasm_get_byte
cmp al, 0xC0
jae .1
dec [disasm_cur_pos]
shr al, 3
and eax, 7
xchg eax, edx
mov eax, [fpuDD+edx*4]
test eax, eax
jz cunk
stosd
mov eax, ' '
stosd
or ch, 0A1h ; qword operand
call disasm_readrmop
and byte [edi], 0
ret
 
.1:
push eax
shr al, 3
and eax, 7
xchg eax, edx
mov eax, dword [fpuDD_2+edx*8]
test eax, eax
jz cerr
stosd
mov eax, dword [fpuDD_2+4+edx*8]
stosd
mov ax, 'st'
stosw
pop eax
and al, 7
add al, '0'
stosb
and byte [edi], 0
ret
 
;-----------------------------------------------------------------------------
 
iglobal
fpuDE dd 'add ','mul ',0,0,'subr','sub ','divr','div '
endg
 
;-----------------------------------------------------------------------------
 
cDE:
call disasm_get_byte
cmp al, 0xC0
jae .1
dec [disasm_cur_pos]
mov word [edi], 'fi'
inc edi
inc edi
shr al, 3
and eax, 7
mov eax, [fpuD8+eax*4]
stosd
mov ax, ' '
stosw
or ch, 81h ; force 16-bit
call disasm_readrmop
and byte [edi], 0
ret
 
.1:
push eax
shr al, 3
and eax, 7
xchg eax, edx
mov eax, [fpuDE+edx*4]
test eax, eax
jz .fcompp
mov byte [edi], 'f'
inc edi
stosd
mov al, 'p'
cmp byte [edi-1], ' '
jnz @f
mov byte [edi-1], al
mov al, ' '
 
@@:
stosb
mov eax, ' st'
stosd
pop eax
and al, 7
add al, '0'
stosb
mov ax, ', '
stosw
mov eax, 'st0'
stosd
ret ; CF cleared
 
.fcompp:
pop eax
cmp al, 0xD9
jnz cerr
mov eax, 'fcom'
stosd
mov ax, 'pp'
stosw
and byte [edi], 0
ret
 
;-----------------------------------------------------------------------------
 
iglobal
fpuDF dd 'ild ',0,'ist ','istp','bld ','ild ','bstp','istp'
endg
 
;-----------------------------------------------------------------------------
 
cDF:
call disasm_get_byte
cmp al, 0xC0
jae .1
dec [disasm_cur_pos]
shr al, 3
and eax, 7
xchg eax, edx
mov eax, [fpuDF+edx*4]
test eax, eax
jz cerr
mov byte [edi], 'f'
inc edi
stosd
mov ax, ' '
stosw
stosb
or ch, 81h ; force 16-bit operand
cmp dl, 4
jb @f
or ch, 20h
test dl, 1
jnz @f
or ch, 40h
 
@@:
call disasm_readrmop
and byte [edi], 0
ret
 
.1:
cmp al, 0xE0
jnz cunk
mov eax, 'fnst'
stosd
mov eax, 'sw '
stosd
mov ax, 'ax'
stosw
and byte [edi], 0
ret
 
;-----------------------------------------------------------------------------
 
cmovd1:
mov eax, 'movd'
stosd
mov eax, ' '
stosd
call disasm_get_byte
dec [disasm_cur_pos]
shr al, 3
and eax, 7
call disasm_write_mmreg
mov ax, ', '
stosw
or ch, 0C0h
and ch, not 1
call disasm_readrmop
and byte [edi], 0
ret
 
;-----------------------------------------------------------------------------
 
cmovd2:
mov eax, 'movd'
stosd
mov eax, ' '
stosd
call disasm_get_byte
dec [disasm_cur_pos]
shr al, 3
and eax, 7
push eax ecx
or ch, 0C0h
and ch, not 1
call disasm_readrmop
mov ax, ', '
stosw
pop ecx eax
call disasm_write_mmreg
and byte [edi], 0
ret
 
;-----------------------------------------------------------------------------
 
cmovq1:
test ch, 1
jz .mm
mov eax, 'movd'
stosd
mov eax, 'qa '
stosd
jmp disasm_mmx1
 
.mm:
mov eax, 'movq'
stosd
mov eax, ' '
stosd
jmp disasm_mmx1
 
;-----------------------------------------------------------------------------
 
cmovq2:
test ch, 1
jz .mm
mov eax, 'movd'
stosd
mov eax, 'qa '
stosd
jmp disasm_mmx3
 
.mm:
mov eax, 'movq'
 
disasm_mmx2:
stosd
mov eax, ' '
stosd
 
disasm_mmx3:
or ch, 50h
call disasm_get_byte
dec [disasm_cur_pos]
push eax
call disasm_readrmop
mov ax, ', '
stosw
pop eax
shr al, 3
and eax, 7
call disasm_write_mmreg
and byte [edi], 0
ret
 
;-----------------------------------------------------------------------------
 
iglobal
mmx_cmds:
db 0x60,'unpcklbw'
db 0x61,'unpcklwd'
db 0x62,'unpckldq'
db 0x63,'packsswb'
db 0x64,'pcmpgtb '
db 0x65,'pcmpgtw '
db 0x66,'pcmpgtd '
db 0x67,'packuswb'
db 0x68,'unpckhbw'
db 0x69,'unpckhwd'
db 0x6A,'unpckhdq'
db 0x6B,'packssdw'
db 0x74,'pcmpeqb '
db 0x75,'pcmpeqw '
db 0x76,'pcmpeqd '
db 0xD4,'paddq '
db 0xD5,'pmullw '
db 0xD8,'psubusb '
db 0xD9,'psubusw '
db 0xDA,'pminub '
db 0xDB,'pand '
db 0xDC,'paddusb '
db 0xDD,'paddusw '
db 0xDE,'pmaxub '
db 0xDF,'pandn '
db 0xE0,'pavgb '
db 0xE3,'pavgw '
db 0xE4,'pmulhuw '
db 0xE5,'pmulhw '
db 0xE8,'psubsb '
db 0xE9,'psubsw '
db 0xEA,'pminsw '
db 0xEB,'por '
db 0xEC,'paddsb '
db 0xED,'paddsw '
db 0xEE,'pmaxsw '
db 0xEF,'pxor '
db 0xF4,'pmuludq '
db 0xF5,'pmaddwd '
db 0xF6,'psadbw '
db 0xF8,'psubb '
db 0xF9,'psubw '
db 0xFA,'psubd '
db 0xFB,'psubq '
db 0xFC,'paddb '
db 0xFD,'paddw '
db 0xFE,'paddd '
endg
 
;-----------------------------------------------------------------------------
 
cpcmn:
mov esi, mmx_cmds
 
@@:
cmp al, [esi]
jz @f
add esi, 9
jmp @b
 
@@:
inc esi
mov al, 'p'
cmp byte [esi], al
jz @f
stosb
 
@@:
movsd
movsd
cmp byte [edi-1], ' '
jz @f
mov al, ' '
stosb
 
; @@:
 
disasm_mmx1:
@@:
or ch, 50h
call disasm_get_byte
dec [disasm_cur_pos]
shr al, 3
and eax, 7
call disasm_write_mmreg
mov ax, ', '
stosw
call disasm_readrmop
cmp word [disasm_string], 'cm'
jz .cmp
and byte [edi], 0
ret
 
.cmp:
call disasm_get_byte
and eax, 7
mov dx, 'eq'
dec eax
js @f
mov dx, 'lt'
jz @f
mov dh, 'e'
dec eax
jnz .no2
 
@@:
xchg dx, word [disasm_string+3]
mov word [disasm_string+5], dx
and byte [edi], 0
ret
 
.no2:
dec eax
jnz @f
add edi, 2
push edi
lea esi, [edi-3]
lea ecx, [esi-(disasm_string+8)+2]
std
rep movsb
cld
mov cx, word [esi-3]
mov dword [esi-3], 'unor'
mov byte [esi+1], 'd'
mov word [esi+2], cx
pop edi
and byte [edi+1], 0
ret
 
@@:
mov edx, 'neq'
dec eax
jz @f
mov edx, 'nlt'
dec eax
jz @f
mov edx, 'nle'
dec eax
jz @f
mov edx, 'ord'
 
@@:
push edi
lea esi, [edi-1]
lea ecx, [esi-(disasm_string+8)+2]
std
rep movsb
cld
mov cx, word [esi-3]
mov dword [esi-3], edx
mov word [esi], cx
pop edi
and byte [edi+1], 0
ret
 
;-----------------------------------------------------------------------------
 
cpsrlw:
mov eax, 'psrl'
jmp @f
 
cpsraw:
mov eax, 'psra'
jmp @f
 
cpsllw:
mov eax, 'psll'
 
@@:
stosd
mov eax, 'w '
stosd
jmp disasm_mmx1
 
cpsrld:
mov eax, 'psrl'
jmp @f
 
cpsrad:
mov eax, 'psra'
jmp @f
 
cpslld:
mov eax, 'psll'
 
@@:
stosd
mov eax, 'd '
stosd
jmp disasm_mmx1
 
cpsrlq:
mov eax, 'psrl'
jmp @f
 
cpsllq:
mov eax, 'psll'
 
@@:
stosd
mov eax, 'q '
stosd
jmp disasm_mmx1
 
;-----------------------------------------------------------------------------
 
csse1:
iglobal
sse_cmds1:
db 0x2F,4,'comi'
db 0x54,3,'and'
db 0x55,4,'andn'
db 0x58,3,'add'
db 0xC2,3,'cmp'
endg
mov esi, sse_cmds1+1
 
.1:
@@:
movzx edx, byte [esi]
cmp al, [esi-1]
jz @f
lea esi, [esi+edx+2]
jmp @b
 
@@:
push ecx
mov ecx, edx
inc esi
rep movsb
pop ecx
mov al, 's'
cmp byte [edi-1], 'i'
jz @f
mov al, 'p'
 
@@:
stosb
mov al, 'd'
test ch, 1
jnz @f
mov al, 's'
 
@@:
stosb
push ecx
push 5
pop ecx
sub ecx, edx
adc ecx, 1
mov al, ' '
rep stosb
pop ecx
or ch, 1 ; force XMM reg
jmp disasm_mmx1
 
;-----------------------------------------------------------------------------
 
csse2:
iglobal
sse_cmds2:
db 0xD0,6,'addsub'
db 0,0
endg
test ch, 1
jz cerr
mov esi, sse_cmds2+1
jmp csse1.1
 
cpshift:
mov dl, al
mov ax, 'ps'
stosw
call disasm_get_byte
push eax
and al, 0xC0
cmp al, 0xC0
jnz .pop_cunk
pop eax
push eax
shr al, 3
and eax, 7
cmp al, 2
jz .rl
cmp al, 4
jz .ra
cmp al, 6
jz .ll
 
.pop_cunk:
pop eax
jmp cunk
 
.ll:
mov ax, 'll'
jmp @f
 
.rl:
mov ax, 'rl'
jmp @f
 
.ra:
cmp dl, 0x73
jz .pop_cunk
mov ax, 'ra'
 
@@:
stosw
mov al, 'w'
cmp dl, 0x71
jz @f
mov al, 'd'
cmp dl, 0x72
jz @f
mov al, 'q'
 
@@:
stosb
mov ax, ' '
stosw
stosb
pop eax
and eax, 7
call disasm_write_mmreg
mov ax, ', '
stosw
xor eax, eax
call disasm_get_byte
call disasm_write_num
and byte [edi], 0
ret
 
;-----------------------------------------------------------------------------
 
iglobal
grp15c1 dq 'fxsave ','fxrstor ','ldmxcsr ','stmxcsr ',0,0,0,'clflush '
endg
 
;-----------------------------------------------------------------------------
 
cgrp15:
call disasm_get_byte
cmp al, 0xC0
jae cunk
shr al, 3
and eax, 7
mov edx, eax
mov eax, dword [grp15c1+eax*8]
test eax, eax
jz cerr
dec [disasm_cur_pos]
stosd
mov eax, dword [grp15c1+4+edx*8]
stosd
or ch, 40h
call disasm_readrmop
and byte [edi], 0
ret
 
; vim: ft=fasm tabstop=4
 
/programs/develop/mtdbg/disasm_tbl.inc
0,0 → 1,70
disasm_table_1:
dd cop22, cop22, cop22, cop22, cop21, cop21, cop0, cop0 ; 0x
dd cop22, cop22, cop22, cop22, cop21, cop21, cop0, cF
dd cop22, cop22, cop22, cop22, cop21, cop21, cop0, cop0 ; 1x
dd cop22, cop22, cop22, cop22, cop21, cop21, cop0, cop0
dd cop22, cop22, cop22, cop22, cop21, cop21, cseges,cop0 ; 2x
dd cop22, cop22, cop22, cop22, cop21, cop21, csegcs,cop0
dd cop22, cop22, cop22, cop22, cop21, cop21, csegss,cop0 ; 3x
dd cop22, cop22, cop22, cop22, cop21, cop21, csegds,cop0
dd cinc1, cinc1, cinc1, cinc1, cinc1, cinc1, cinc1, cinc1 ; 4x
dd cdec1, cdec1, cdec1, cdec1, cdec1, cdec1, cdec1, cdec1
dd cpush1,cpush1,cpush1,cpush1,cpush1,cpush1,cpush1,cpush1 ; 5x
dd cpop1, cpop1, cpop1, cpop1, cpop1, cpop1, cpop1, cpop1
dd cop0, cop0, cbound,carpl, csegfs,cseggs,c66, c67 ; 6x
dd cpush21,cimul1,cpush22,cimul1,cunk,cunk, cunk, cunk
dd cjcc1, cjcc1, cjcc1, cjcc1, cjcc1, cjcc1, cjcc1, cjcc1 ; 7x
dd cjcc1, cjcc1, cjcc1, cjcc1, cjcc1, cjcc1, cjcc1, cjcc1
dd cop23, cop23, cop23, cop23, cop22, cop22, cop22, cop22 ; 8x
dd cop22, cop22, cop22, cop22, cunk, cop22, cunk, cpop2
dd cop0, cxchg1,cxchg1,cxchg1,cxchg1,cxchg1,cxchg1,cxchg1 ; 9x
dd ccbw, ccwd, ccallf,cop0, cop0, cop0, cop0, cop0
dd cmov3, cmov3, cmov3, cmov3, cop0, cop0, cop0, cop0 ; Ax
dd cop21, cop21, cop0, cop0, cop0, cop0, cop0, cop0
dd cmov11,cmov11,cmov11,cmov11,cmov11,cmov11,cmov11,cmov11 ; Bx
dd cmov12,cmov12,cmov12,cmov12,cmov12,cmov12,cmov12,cmov12
dd cshift1,cshift1,cret2,cop0, cunk, cunk, cmov2, cmov2 ; Cx
dd center,cop0, cunk, cunk, cop0, cint, cunk, cunk
dd cshift2,cshift2,cshift3,cshift3,caam,caad,cunk, cxlat ; Dx
dd cD8, cD9, cDA, cDB, cDC, cDD, cDE, cDF
dd cloopnz,cloopz,cloop,cjcxz, cunk, cunk, cunk, cunk ; Ex
dd ccall1,cjmp1, cunk, cjmp2, cunk, cunk, cunk, cunk
dd clock, cunk, crepnz,crep, cunk, cop0, cop1, cop1 ; Fx
dd cop0, cop0, cop0, cop0, cop0, cop0, cop1, cop1
 
disasm_table_2:
dd cunk, cunk, cunk, cunk, cunk, cop0_F,cop0_F,cunk ; 0x
dd cunk, cunk, cunk, cunk, cunk, cunk, cunk, cunk
dd cunk, cunk, cunk, cunk, cunk, cunk, cunk, cunk ; 1x
dd cunk, cunk, cunk, cunk, cunk, cunk, cunk, cunk
dd cunk, cunk, cunk, cunk, cunk, cunk, cunk, cunk ; 2x
dd cunk, cunk, cunk, cunk, cunk, cunk, cunk, csse1
dd cunk, crdtsc,cunk, cunk, cop0_F,cunk, cunk, cunk ; 3x
dd cunk, cunk, cunk, cunk, cunk, cunk, cunk, cunk
dd cmovcc,cmovcc,cmovcc,cmovcc,cmovcc,cmovcc,cmovcc,cmovcc ; 4x
dd cmovcc,cmovcc,cmovcc,cmovcc,cmovcc,cmovcc,cmovcc,cmovcc
dd cunk, cunk, cunk, cunk, csse1, csse1, cunk, cunk ; 5x
dd csse1, cunk, cunk, cunk, cunk, cunk, cunk, cunk
dd cpcmn, cpcmn, cpcmn, cpcmn, cpcmn, cpcmn, cpcmn, cpcmn ; 6x
dd cpcmn, cpcmn, cpcmn, cpcmn, cunk, cunk, cmovd1,cmovq1
dd cunk, cpshift,cpshift,cpshift,cpcmn,cpcmn,cpcmn,cemms ; 7x
dd cunk, cunk, cunk, cunk, cunk, cunk, cmovd2,cmovq2
dd cjcc2, cjcc2, cjcc2, cjcc2, cjcc2, cjcc2, cjcc2, cjcc2 ; 8x
dd cjcc2, cjcc2, cjcc2, cjcc2, cjcc2, cjcc2, cjcc2, cjcc2
dd csetcc,csetcc,csetcc,csetcc,csetcc,csetcc,csetcc,csetcc ; 9x
dd csetcc,csetcc,csetcc,csetcc,csetcc,csetcc,csetcc,csetcc
dd cunk, cunk, ccpuid,cbtx2, cshld, cshld, cunk, cunk ; Ax
dd cunk, cunk, cunk, cbtx2, cshrd, cshrd, cgrp15,cop22
dd ccmpxchg,ccmpxchg,cunk,cbtx2,cunk, cunk, cmovzx,cmovzx ; Bx
dd cunk, cunk, cbtx1, cbtx2, cbsf, cbsr, cmovsx,cmovsx
dd cunk, cunk, csse1, cunk, cunk, cunk, cunk, ccmpxchg8b ; Cx
dd cbswap,cbswap,cbswap,cbswap,cbswap,cbswap,cbswap,cbswap
dd csse2, cpsrlw,cpsrlw,cpsrlq,cpcmn, cpcmn, cunk, cunk ; Dx
dd cpcmn, cpcmn, cpcmn, cpcmn, cpcmn, cpcmn, cpcmn, cpcmn
dd cpcmn, cpsraw,cpsrad,cpcmn, cpcmn, cpcmn, cunk, cunk ; Ex
dd cpcmn, cpcmn, cpcmn, cpcmn, cpcmn, cpcmn, cpcmn, cpcmn
dd cunk, cpsllw,cpslld,cpsllq,cpcmn, cpcmn, cpcmn, cunk ; Fx
dd cpcmn, cpcmn, cpcmn, cpcmn, cpcmn, cpcmn, cpcmn, cunk
 
; vim: ft=fasm tabstop=4
 
/programs/develop/mtdbg/gui.inc
0,0 → 1,1647
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; GUI ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
;-----------------------------------------------------------------------------
; Color scheme
 
; format - 0xRRGGBB
COLOR_BG_NORMAL equ 0x101010 ; was 0xFFFFFF white
COLOR_BG_BREAKPOINT equ 0xFF0000 ; red
COLOR_BG_SELECTED equ 0x0000FF ; blue
COLOR_LINE equ 0xFFFFFF ; was 0x000000 black
COLOR_TXT_NORMAL equ 0xFFFFFF ; was 0x000000 black
COLOR_TXT_INACTIVE equ 0x808080 ; grey
COLOR_TXT_CHANGED equ 0x00AA00 ; green
COLOR_TXT_SELECTED equ 0xFFFFFF ; white
 
;-----------------------------------------------------------------------------
 
data_width equ 80
data_x_pos equ 12
data_x_size equ data_width*6
 
title_x_pos equ 30
title_y_pos equ 32
title_y_size equ 10
 
;dump_y_pos equ (registers_y_pos + registers_y_size + 5)
dump_y_pos equ (title_y_pos + title_y_size)
dump_height equ 6
dump_y_size equ (dump_height*10)
 
disasm_y_pos equ (dump_y_pos + dump_y_size + 4)
disasm_height equ 18
disasm_y_size equ (disasm_height*10)
 
messages_width equ data_width
messages_height equ 8
messages_x_pos equ data_x_pos
messages_y_pos equ (disasm_y_pos + disasm_y_size + 4)
messages_x_size equ messages_width*6
messages_y_size equ messages_height*10
 
cmdline_width equ data_width
cmdline_x_pos equ data_x_pos
cmdline_y_pos equ (messages_y_pos + messages_y_size + 4)
cmdline_x_size equ messages_x_size
cmdline_y_size equ 10
 
registers_x_pos equ (data_x_pos + messages_x_size + 4)
registers_y_pos equ (title_y_pos + title_y_size - 3)
registers_x_size equ 134
registers_y_size equ (cmdline_y_pos + cmdline_y_size - registers_y_pos+1)
 
wnd_x_size equ (data_x_pos + messages_x_size + data_x_pos + registers_x_size+3)
wnd_y_size equ (cmdline_y_pos + cmdline_y_size + data_x_pos)
 
;-----------------------------------------------------------------------------
; Entry point
 
; TODO: split all gui part in independent function, move entry point into mtdbg.asm
 
start:
; initialize process heap
mcall 68, 11
mov edi, messages
mov ecx, messages_width*messages_height
mov al, ' '
rep stosb
xor eax, eax
mov [messages_pos], eax
mov [cmdline_len], eax
mov [cmdline_pos], eax
mov edi, needzerostart
mov ecx, (needzeroend-needzerostart+3)/4
rep stosd
mov esi, begin_str
call put_message_nodraw
; set event mask - default events and debugging events
;push 40
;pop eax
;mov ebx, 0x107
mcall 40, 0x107
; set debug messages buffer
mov ecx, dbgbufsize
mov dword [ecx], 256
xor ebx, ebx
mov [ecx+4], ebx
mov al, 69
mcall
mov esi, i_param
call get_arg.skip_spaces
test al, al
jz dodraw
push esi
call draw_window
pop esi
call OnLoadInit
jmp waitevent
 
dodraw:
call draw_window
 
waitevent:
;push 10
;pop eax
mcall 10
cmp al, 9
jz debugmsg
dec eax
jz dodraw
dec eax
jz keypressed
dec eax
jnz waitevent
; button pressed - we have only one button (close)
;push -1
;pop eax
mcall -1
 
; TODO: split in more independent function
keypressed:
mov al, 2
mcall
shr eax, 8
cmp al, 8
jz .backspace
cmp al, 0xB0
jz .left
cmp al, 0xB3
jz .right
cmp al, 0x0D
jz .enter
cmp al, 0xB6
jz .del
cmp al, 0xB4
jz .home
cmp al, 0xB5
jz .end
cmp al, 0xB1
jz .down
cmp al, 0xB2
jz .up
cmp al, 0xD8
jz CtrlF7
cmp al, 0xD9
jz CtrlF8
cmp [cmdline_len], cmdline_width
jae waitevent
push eax
call clear_cmdline_end
pop eax
mov edi, cmdline
mov ecx, [cmdline_len]
add edi, ecx
lea esi, [edi-1]
sub ecx, [cmdline_pos]
std
rep movsb
cld
stosb
inc [cmdline_len]
call draw_cmdline_end
inc [cmdline_pos]
call draw_cursor
jmp waitevent
 
.backspace:
cmp [cmdline_pos], 0
jz waitevent
dec [cmdline_pos]
 
.delchar:
call clear_cmdline_end
mov edi, [cmdline_pos]
dec [cmdline_len]
mov ecx, [cmdline_len]
sub ecx, edi
add edi, cmdline
lea esi, [edi+1]
rep movsb
call draw_cmdline_end
call draw_cursor
jmp waitevent
 
.del:
mov eax, [cmdline_pos]
cmp eax, [cmdline_len]
jae waitevent
jmp .delchar
 
.left:
cmp [cmdline_pos], 0
jz waitevent
call hide_cursor
dec [cmdline_pos]
call draw_cursor
jmp waitevent
 
.right:
mov eax, [cmdline_pos]
cmp eax, [cmdline_len]
jae waitevent
call hide_cursor
inc [cmdline_pos]
call draw_cursor
jmp waitevent
 
.home:
call hide_cursor
and [cmdline_pos], 0
call draw_cursor
jmp waitevent
 
.end:
call hide_cursor
mov eax, [cmdline_len]
mov [cmdline_pos], eax
call draw_cursor
 
.up:
.down:
jmp waitevent
 
; We also trying to execute previous command, if empty command_line
.enter:
mov ecx, [cmdline_len]
test ecx, ecx
jnz .exec_cur
mov cl, byte [cmdline_prev]
cmp cl, 0
jz waitevent
 
.exec_prev:
mov esi, cmdline_prev
jmp .exec
 
.exec_cur:
mov esi, cmdline
 
.exec:
mov byte [esi+ecx], 0
and [cmdline_pos], 0
push esi
call clear_cmdline_end
call draw_cursor
pop esi
and [cmdline_len], 0
; skip leading spaces
call get_arg.skip_spaces
cmp al, 0
jz waitevent
; now esi points to command
push esi
mov esi, prompt
call put_message_nodraw
pop esi
push esi
call put_message_nodraw
 
; TODO: add meaningful name
z1:
mov esi, newline
call put_message
pop esi
push esi
call get_arg
mov [curarg], esi
pop edi
mov esi, commands
call find_cmd
mov eax, aUnknownCommand
jc .x11
 
; check command requirements
; flags field:
; &1: command may be called without parameters
; &2: command may be called with parameters
; &4: command may be called without loaded program
; &8: command may be called with loaded program
mov eax, [esi+8]
mov ecx, [curarg]
cmp byte [ecx], 0
jz .noargs
test byte [esi+16], 2
jz .x11
jmp @f
 
.noargs:
test byte [esi+16], 1
jz .x11
 
@@:
cmp [debuggee_pid], 0
jz .nodebuggee
mov eax, aAlreadyLoaded
test byte [esi+16], 8
jz .x11
jmp .x9
 
.nodebuggee:
mov eax, need_debuggee
test byte [esi+16], 4
jnz .x9
 
.x11:
xchg esi, eax
call put_message
 
; store cmdline for repeating
.x10:
mov esi, cmdline
mov ecx, [cmdline_len]
 
@@:
cmp ecx, 0
jle .we
mov al, [esi + ecx]
mov [cmdline_prev + ecx], al
dec ecx
jmp @b
 
.we:
mov [cmdline_len], 0
jmp waitevent
 
.x9:
call dword [esi+4]
jmp .x10
 
;-----------------------------------------------------------------------------
; Cmdline handling
 
clear_cmdline_end:
mov ebx, [cmdline_pos]
mov ecx, [cmdline_len]
sub ecx, ebx
;push 13
;pop eax
imul ebx, 6
imul ecx, 6
inc ecx
add ebx, cmdline_x_pos
shl ebx, 16
or ebx, ecx
mov ecx, cmdline_y_pos*10000h + cmdline_y_size
; setting up container color scheme
; COLOR_BG_NORMAL was 0xFFFFFF
mov edx, COLOR_BG_NORMAL
; draw container rectangle/box for cmdline
mcall 13
ret
 
draw_cmdline:
xor ebx, ebx
jmp @f
 
; TODO: make it local
draw_cmdline_end:
mov ebx, [cmdline_pos]
 
@@:
mov esi, [cmdline_len]
sub esi, ebx
;push 4
;pop eax
; setting up text color scheme and attributes
; was 'xor ecx, ecx'
mov ecx, COLOR_TXT_NORMAL
lea edx, [cmdline+ebx]
imul ebx, 6
add ebx, cmdline_x_pos
shl ebx, 16
or ebx, cmdline_y_pos+1
; draw a text string in the window, color in ecx
mcall 4
ret
 
;-----------------------------------------------------------------------------
; Working with messages
; in: esi->ASCIIZ message
put_message_nodraw:
mov edx, [messages_pos]
 
.m:
lea edi, [messages+edx]
 
.l:
lodsb
cmp al, 0
jz .done
call test_scroll
cmp al, 10
jz .newline
cmp al, '%'
jnz @f
cmp dword [esp], z1
jnz .format
 
@@:
stosb
inc edx
jmp .l
 
.newline:
push edx
mov ecx, messages_width
xor eax, eax
xchg eax, edx
div ecx
xchg eax, edx
pop edx
test eax, eax
jz .m
sub edx, eax
add edx, ecx
jmp .m
 
.done:
mov [messages_pos], edx
ret
 
; at this moment all format specs must be %<digit>X
.format:
lodsb ; get <digit>
sub al, '0'
movzx ecx, al
lodsb
pop eax
pop ebp
push eax
; write number in ebp with ecx digits
dec ecx
shl ecx, 2
 
.writenibble:
push ecx
call test_scroll
pop ecx
mov eax, ebp
shr eax, cl
and al, 0xF
cmp al, 10
sbb al, 69h
das
stosb
inc edx
sub ecx, 4
jns .writenibble
jmp .l
 
test_scroll:
cmp edx, messages_width*messages_height
jnz .ret
push esi
mov edi, messages
lea esi, [edi+messages_width]
mov ecx, (messages_height-1)*messages_width/4
rep movsd
push eax
mov al, ' '
push edi
push messages_width
pop ecx
sub edx, ecx
rep stosb
pop edi
pop eax
pop esi
 
.ret:
ret
 
;-----------------------------------------------------------------------------
 
put_message:
call put_message_nodraw
 
draw_messages:
;push 13
;pop eax
;mov edx, 0xFFFFFF
;mov ebx, messages_x_pos*10000h+messages_x_size
;mov ecx, messages_y_pos*10000h+messages_y_size
; draw container rectanle/box
; COLOR_BG_NORMAL was 0xFFFFFF
mcall 13, messages_x_pos*10000h+messages_x_size, messages_y_pos*10000h+messages_y_size, COLOR_BG_NORMAL
mov edx, messages
push messages_width
pop esi
; setting up text color scheme/attributes
; was 'xor ecx, ecx'
mov ecx, COLOR_TXT_NORMAL
;mov al, 4
mov ebx, messages_x_pos*10000h+messages_y_pos
 
@@:
; display text string in the window
mcall 4
add edx, esi
add ebx, 10
cmp edx, messages+messages_width*messages_height
jb @b
ret
 
;-----------------------------------------------------------------------------
; Show/hide cursor in command line
 
; TODO: make it cursor.draw and cursor.hide ???
draw_cursor:
;push 38
;pop eax
mov ecx, cmdline_y_pos*10001h+cmdline_y_size-1
mov ebx, [cmdline_pos]
imul ebx, 6
add ebx, cmdline_x_pos
mov edx, ebx
shl ebx, 16
or ebx, edx
; setting line color
; was 'xor edx, edx' - black
mov edx, COLOR_LINE
; draw line, color in edx
mcall 38
ret
 
hide_cursor:
mov ebx, [cmdline_pos]
;push 13
;pop eax
imul ebx, 6
add ebx, cmdline_x_pos
shl ebx, 16
inc ebx
mov ecx, cmdline_y_pos*10000h + cmdline_y_size
; setting up rectangle color
; was 0xFFFFFF
mov edx, COLOR_BG_NORMAL
; draw container rectangle/box
mcall 13
mov ebx, [cmdline_pos]
cmp ebx, [cmdline_len]
jae .ret
;mov al, 4
; setting up text color scheme and attributes
;was 'xor ecx, ecx'
mov ecx, COLOR_TXT_NORMAL
lea edx, [cmdline+ebx]
imul ebx, 6
add ebx, cmdline_x_pos
shl ebx, 16
or ebx, cmdline_y_pos+1
push 1
pop esi
; draw text string in the window
mcall 4
 
.ret:
ret
 
;-----------------------------------------------------------------------------
; Draw program window title
 
; FIXME: something wrong here
redraw_title:
;push 13
;pop eax
;mov edx, 0xFFFFFF
;mov ebx, title_x_pos*10000h + data_x_pos+data_x_size-title_x_pos
;mov ecx, title_y_pos*10000h + title_y_size
; draw container rectangle/box
; color was 0xFFFFFF
mcall 13, title_x_pos*10000h+data_x_pos+data_x_size-title_x_pos, title_y_pos*10000h+title_y_size, COLOR_BG_NORMAL
 
draw_title:
;mov al, 38
;mov ebx, (data_x_pos-2)*10000h + title_x_pos-5
;mov ecx, (title_y_pos+5)*10001h
; draw line with COLOR_LINE (in edx)
; was 'xor edx, edx'
mcall 38, (data_x_pos-2)*10000h+title_x_pos-5, (title_y_pos+5)*10001h, COLOR_LINE
push NoPrgLoaded_len
pop esi
cmp [debuggee_pid], 0
jz @f
mov esi, [prgname_len]
 
@@:
imul ebx, esi, 6
add ebx, title_x_pos+4
shl ebx, 16
mov bx, data_x_pos+data_x_size-10-5-6*7
cmp [bSuspended], 0
jz @f
add ebx, 6
 
@@:
; draw line with COLOR_LINE (in edx)
mcall
mov ebx, (data_x_pos+data_x_size-10+4)*0x10000 + data_x_pos+data_x_size+2
; draw line with COLOR_LINE (in edx)
mcall
mov al, 4
mov ebx, title_x_pos*10000h+title_y_pos
; setting up text color scheme and attributes
; was 'xor ecx, ecx'
mov ecx, COLOR_TXT_NORMAL
mov edx, NoPrgLoaded_str
cmp [debuggee_pid], 0
jz @f
mov edx, [prgname_ptr]
 
@@:
; draw text string in the window
mcall
cmp [debuggee_pid], 0
jz .nodebuggee
mov ebx, (data_x_pos+data_x_size-10-6*7)*10000h + title_y_pos
mov edx, aRunning
push 7
pop esi
cmp [bSuspended], 0
jz @f
add ebx, 6*10000h
mov edx, aPaused
dec esi
 
@@:
; draw line with COLOR_LINE (in edx) in one case
; and draw text string with color COLOR_TXT_NORMAL (in ecx) in another
mcall
ret
 
.nodebuggee:
mov al, 38
mov ebx, (data_x_pos+data_x_size-10-6*7-5)*0x10000 + data_x_pos+data_x_size+2
mov ecx, (title_y_pos+5)*10001h
; setting up line color scheme
; was 'xor edx, edx'
mov edx, COLOR_LINE
jmp @b
 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;; REGISTERS PANEL ;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
;-----------------------------------------------------------------------------
; Display common register content
 
; TODO: add format support (e.g. numerical value, or address offset/pointer)
 
; in: esi->value, edx->string, ecx = string length, ebx = coord
draw_register:
push edx
push ecx
push esi
mov eax, esi
mov esi, ecx
; setting up registers colors
; can be usual, inactive and changed
; inactive color
; was 0x40808080 - grey
mov ecx, (COLOR_TXT_INACTIVE or 0x40000000)
cmp [debuggee_pid], 0
jz .cd
cmp [bSuspended], 0
jz .cd
; normal color
; was 0x40000000 - black
mov ecx, (COLOR_TXT_NORMAL or 0x40000000)
push edi
mov edi, [eax]
cmp dword [eax+oldcontext-context], edi
pop edi
jz .cd
; changed register color
; was 0x4000AA00 - green
mov ecx, (COLOR_TXT_CHANGED or 0x40000000)
 
.cd:
;push 4
;pop eax
; draw a text string in the window
mcall 4
imul esi, 60000h
lea edx, [ebx+esi]
;mov al, 47
;mov ebx, 80101h
mov esi, ecx
pop ecx
; draw a number in the window
; color in the esi (same value as for usual text)
mcall 47, 80101h
lea ebx, [edx+60000h*18]
mov esi, ecx
pop ecx
pop edx
add edx, ecx
ret
 
;-----------------------------------------------------------------------------
; Display FPU register (ST0 - ST7) content
;
; in: esi->value, edx->string, ecx = string length, ebx = coord
draw_fpu_register:
push edx
push ecx
push esi
mov eax, esi
mov esi, ecx
; setting up registers color
; can be usual, inactive and changed
; inactive color
; was 0x40808080 - grey
mov ecx, (COLOR_TXT_INACTIVE or 0x40000000)
cmp [debuggee_pid], 0
jz .cd
cmp [bSuspended], 0
jz .cd
; normal color
; was 0x40000000 - black
mov ecx, (COLOR_TXT_NORMAL or 0x40000000)
push edi
mov edi, [eax]
cmp dword [eax+oldcontext-context], edi
pop edi
jnz .scol
push edi
mov edi, [eax+4]
cmp dword [eax+oldcontext-context+4], edi
pop edi
jz .cd
 
.scol:
; changed register color
; was 0x4000AA00 - green
mov ecx, (COLOR_TXT_CHANGED or 0x40000000)
 
.cd:
;push 4
;pop eax
; draw a text string in the window
mcall 4
imul esi, 60000h
lea edx, [ebx+esi]
;mov al, 47
;mov ebx, 40100101h ; [20] show 16 chars set [30] bit - qword
mov esi, ecx
pop ecx
; draw a number in the window
; color is the same as for previous text draw function
; ebx : [20] show 16 chars set [30] bit - qword
mcall 47, 40100101h
lea ebx, [edx+60000h*18]
mov esi, ecx
pop ecx
pop edx
add edx, ecx
ret
 
;-----------------------------------------------------------------------------
; Show FPU MMX register content
;
; in: esi->value, edx->string, ecx = string length, ebx = coord
draw_mmx_register:
push edx
push ecx
push esi
mov eax, esi
mov esi, ecx
; setting up registers color
; can be usual, inactive and changed
; inactive color
; was 0x40808080 - grey
mov ecx, (COLOR_TXT_INACTIVE or 0x40000000)
cmp [debuggee_pid], 0
jz .cd
cmp [bSuspended], 0
jz .cd
; normal color
; was 0x40000000 - black
mov ecx, (COLOR_TXT_NORMAL or 0x40000000)
push edi
mov edi, [eax]
cmp dword [eax+oldcontext-context], edi
pop edi
jnz .scol
push edi
mov edi, [eax+4]
cmp dword [eax+oldcontext-context+4], edi
pop edi
jz .cd
 
.scol:
; changed color
; was 0x4000AA00 - green
mov ecx, (COLOR_TXT_CHANGED or 0x40000000)
 
.cd:
;push 4
;pop eax
; draw a text string in the window
mcall 4
imul esi, 60000h
lea edx, [ebx+esi]
;mov al, 47
;mov ebx, 40100101h ; [20] show 16 chars set [30] bit - qword
mov esi, ecx
pop ecx
; draw a number in the window
; color is the same as for previous draw text function
; ebx : [20] show 16 chars set [30] bit - qword
mcall 47, 40100101h
lea ebx, [edx+60000h*18]
mov esi, ecx
pop ecx
pop edx
add edx, ecx
ret
 
; TODO add SSE registers
; TODO add AVX registers
 
;-----------------------------------------------------------------------------
; Display contents of EFLAGS register
draw_flag:
movzx edi, byte [edx+7]
bt [_eflags], edi
jc .on
or byte [edx], 20h
jmp .onoff
 
.on:
and byte [edx], not 20h
 
.onoff:
; setting up registers colors
; can be usual, inactive and changed
; inactive color
; was 0x40808080 - grey
mov ecx, (COLOR_TXT_INACTIVE or 0x40000000)
cmp [debuggee_pid], 0
jz .doit
cmp [bSuspended], 0
jz .doit
; normal color
; was 0x40000000 - black
mov ecx, (COLOR_TXT_NORMAL or 0x40000000)
bt [_eflags], edi
lahf
bt dword [_eflags + oldcontext - context], edi
rcl ah, 1
test ah, 3
jp .doit
; changed color
; was 0x4000AA00 - green
mov ecx, (COLOR_TXT_CHANGED or 0x40000000)
 
.doit:
mov ah, 0
; background color for text string or number
; was 0xFFFFFF - white
mov edi, COLOR_BG_NORMAL
; draw a text string in the window in one case
; and a number in another
; color scheme same as for previously called function (was in ecx)
mcall
ret
 
;-----------------------------------------------------------------------------
; Draw registers frame title
 
; Also show current register set (common + MMX, SSE or AVX)
draw_reg_title:
;push 4
;pop eax
; setting up text backround color
; was 0xFFFFFF - white
mov edi, COLOR_BG_NORMAL
; setting up text color
; can be usual and inactive
; normal color
; was 0x40000000 - black
mov ecx, (COLOR_TXT_NORMAL or 0x40000000)
mov esi, 7
cmp [reg_mode], REG_MODE_CPU
jz @f
; inactive color
; was 0x40808080 - grey
mov ecx, (COLOR_TXT_INACTIVE or 0x40000000)
 
@@:
mov edx, aMain
;mov ebx, (registers_x_pos+4)*10000h + registers_y_pos+2
; draw a text string in the window
mcall 4, (registers_x_pos+4)*10000h+registers_y_pos+2
cmp [reg_mode], REG_MODE_SSE
jz @f
; inactive color
; was 0x40808080 - grey
mov ecx, (COLOR_TXT_INACTIVE or 0x40000000)
 
@@:
mov edx, aSSE
;mov ebx, (registers_x_pos+46)*10000h + registers_y_pos+2
; draw a text string in the window
mcall 4, (registers_x_pos+46)*10000h+registers_y_pos+2
cmp [reg_mode], REG_MODE_AVX
jz @f
; inactive color
; was 0x40808080 - grey
mov ecx, (COLOR_TXT_INACTIVE or 0x40000000)
 
@@:
mov edx, aAVX
;mov ebx, (registers_x_pos+88)*10000h + registers_y_pos+2
; draw a text string in the window
mcall 4, (registers_x_pos+88)*10000h+registers_y_pos+2
ret
 
;-----------------------------------------------------------------------------
; Display common registers set + MMX + FPU
 
draw_main_registers:
;push 13
;pop eax
;mov edx, 0xFFFFFF
;mov ebx, (registers_x_pos-1)*10000h + (registers_x_size+2)
;mov ecx, (registers_y_pos-1)*10000h + (registers_y_size+2)
; draw container rectangle/box with COLOR_BG_NORMAL
; color in edx, was 0xFFFFFF - white
mcall 13, (registers_x_pos-1)*10000h+(registers_x_size+2), (registers_y_pos-1)*10000h+(registers_y_size+2), COLOR_BG_NORMAL
 
; TODO: add support for FPU ST0-ST7 registers
.redraw:
; setting up background color for text and numbers output
; was 0xFFFFFF - white
mov edi, COLOR_BG_NORMAL
mov esi, _eax
push 4
pop ecx
mov edx, regs_strs
mov ebx, (registers_x_pos+2)*10000h+registers_y_pos+22
call draw_register
mov ebx, (registers_x_pos+2)*10000h+registers_y_pos+32
add esi, _ebx-_eax
call draw_register
mov ebx, (registers_x_pos+2)*10000h+registers_y_pos+42
add esi, _ecx-_ebx
call draw_register
mov ebx, (registers_x_pos+2)*10000h+registers_y_pos+52
add esi, _edx-_ecx
call draw_register
mov ebx, (registers_x_pos+2)*10000h+registers_y_pos+62
add esi, _esi-_edx
call draw_register
mov ebx, (registers_x_pos+2)*10000h+registers_y_pos+72
add esi, _edi-_esi
call draw_register
mov ebx, (registers_x_pos+2)*10000h+registers_y_pos+82
add esi, _ebp-_edi
call draw_register
mov ebx, (registers_x_pos+2)*10000h+registers_y_pos+92
add esi, _esp-_ebp
call draw_register
mov ebx, (registers_x_pos+2)*10000h+registers_y_pos+102
add esi, _eip-_esp
call draw_register
mov ebx, (registers_x_pos+2)*10000h+registers_y_pos+112
push cx
mov cl, 7
add esi, _eflags-_eip
call draw_register
pop cx
 
; MMX registers
mov edx, mmx_strs
mov ebx, (registers_x_pos+2)*10000h+registers_y_pos+142
mov esi, _mm0
call draw_mmx_register
mov ebx, (registers_x_pos+2)*10000h+registers_y_pos+152
add esi, _mm1-_mm0
call draw_mmx_register
mov ebx, (registers_x_pos+2)*10000h+registers_y_pos+162
add esi, _mm2-_mm1
call draw_mmx_register
mov ebx, (registers_x_pos+2)*10000h+registers_y_pos+172
add esi, _mm3-_mm2
call draw_mmx_register
mov ebx, (registers_x_pos+2)*10000h+registers_y_pos+182
add esi, _mm4-_mm3
call draw_mmx_register
mov ebx, (registers_x_pos+2)*10000h+registers_y_pos+192
add esi, _mm5-_mm4
call draw_mmx_register
mov ebx, (registers_x_pos+2)*10000h+registers_y_pos+202
add esi, _mm6-_mm5
call draw_mmx_register
mov ebx, (registers_x_pos+2)*10000h+registers_y_pos+212
add esi, _mm7-_mm6
call draw_mmx_register
;mov al, 4
; setting up text color
; inactive color
; was 0x808080 - grey
mov ecx, COLOR_TXT_INACTIVE
cmp [debuggee_pid], 0
jz @f
cmp [bSuspended], 0
jz @f
xor ecx, ecx
 
@@:
mov edx, aColon
xor esi, esi
inc esi
;mov ebx, (registers_x_pos+10)*10000h + registers_y_pos+122
; draw a text string in the window, color in ecx
mcall 4, (registers_x_pos+10)*10000h+registers_y_pos+122
mov edx, flags
 
@@:
add ebx, 2*6*10000h
call draw_flag
inc edx
cmp dl, flags_bits and 0xFF
jnz @b
ret
 
;-----------------------------------------------------------------------------
; Draw SSE registers set
 
draw_sse_registers:
.redraw:
ret
 
;-----------------------------------------------------------------------------
; Draw AVX registers set
 
draw_avx_registers:
.redraw:
ret
 
;-----------------------------------------------------------------------------
; Draw all registers sets
draw_registers:
call draw_reg_title
cmp [reg_mode], REG_MODE_CPU
jnz @f
call draw_main_registers
ret
 
@@:
cmp [reg_mode], REG_MODE_SSE
jnz @f
call draw_sse_registers
ret
 
@@:
call draw_avx_registers
ret
 
.redraw:
call draw_reg_title
cmp [reg_mode], REG_MODE_CPU
jnz @f
call draw_main_registers.redraw
ret
 
@@:
cmp [reg_mode], REG_MODE_SSE
jnz @f
call draw_sse_registers.redraw
ret
 
@@:
call draw_avx_registers.redraw
ret
 
;-----------------------------------------------------------------------------
; Display memory dump
 
draw_dump:
;push 13
;pop eax
;mov edx, 0xFFFFFF
;mov ebx, data_x_pos*10000h + data_x_size
;mov ecx, dump_y_pos*10000h + dump_y_size
; draw container rectangle/box in the window
; with color in COLOR_BG_NORMAL (was 0xFFFFFF - white)
mcall 13, data_x_pos*10000h+data_x_size, dump_y_pos*10000h+dump_y_size, COLOR_BG_NORMAL
 
.redraw:
; addresses
;mov al, 47
mov ebx, 80100h
mov edx, data_x_pos*10000h + dump_y_pos
mov ecx, [dumppos]
; background color for text string
; was 0xFFFFFF - white
mov edi, COLOR_BG_NORMAL
; inactive color
; was 0x40808080 - grey
mov esi, (COLOR_TXT_INACTIVE or 0x40000000)
cmp [debuggee_pid], 0
jz @f
cmp [bSuspended], 0
jz @f
; normal color
; was 0x40000000 - black
mov esi, (COLOR_TXT_NORMAL or 0x40000000)
 
@@:
; draw a number in the window, color in esi
mcall 47
add ecx, 10h
add edx, 10
cmp dl, dump_y_pos + dump_y_size
jb @b
; hex dump of data
mov ecx, dumpdata
push ecx
xor ebx, ebx
mov edx, (data_x_pos+12*6)*10000h + dump_y_pos
cmp [dumpread], ebx
jz .hexdumpdone1
 
.hexdumploop1:
push ebx
mov ebx, 20101h
; draw a number in the window, color in esi
mcall
pop ebx
add edx, 3*6*10000h
inc ecx
inc ebx
test bl, 15
jz .16
test bl, 7
jnz @f
add edx, 2*6*10000h - 10 + 6*(3*10h+2)*10000h
 
.16:
add edx, 10 - 6*(3*10h+2)*10000h
 
@@:
cmp ebx, [dumpread]
jb .hexdumploop1
 
.hexdumpdone1:
mov al, 4
; copy color value from esi to ecx
; to draw text string with 'mcall 4'
mov ecx, esi
xchg ebx, edx
push 2
pop esi
 
.hexdumploop2:
cmp edx, dump_height*10h
jae .hexdumpdone2
push edx
mov edx, aQuests
; draw text string with color in ecx, copied from esi
mcall
pop edx
add ebx, 3*6*10000h
inc edx
test dl, 15
jz .16x
test dl, 7
jnz .hexdumploop2
add ebx, 2*6*10000h - 10 + 6*(3*10h+2)*10000h
 
.16x:
add ebx, 10 - 6*(3*10h+2)*10000h
jmp .hexdumploop2
 
.hexdumpdone2:
dec esi
; colon, minus signs
mov ebx, (data_x_pos+8*6)*10000h + dump_y_pos
mov edx, aColon
 
@@:
mcall
add ebx, 10
cmp bl, dump_y_pos+dump_height*10
jb @b
mov ebx, (data_x_pos+(12+3*8)*6)*10000h + dump_y_pos
mov edx, aMinus
 
@@:
mcall
add ebx, 10
cmp bl, dump_y_pos+dump_height*10
jb @b
; ASCII data
mov ebx, (data_x_pos+(12+3*10h+2+2)*6)*10000h + dump_y_pos
pop edx
push dump_height*10h
 
.asciiloop:
push edx
cmp byte [edx], 20h
jae @f
mov edx, aPoint
 
@@:
; draw a text string in the window, color in ecx
mcall
pop edx
inc edx
add ebx, 6*10000h
dec dword [esp]
jz .asciidone
test byte [esp], 15
jnz .asciiloop
add ebx, 10 - 6*10h*10000h
jmp .asciiloop
 
.asciidone:
pop ecx
ret
 
;-----------------------------------------------------------------------------
; Display disassembled code
 
; @@@@@ WAS:
; redraw_disasm:
; push 13
; pop eax
; mov edx, 0xFFFFFF
; mov ebx, data_x_pos*10000h + data_x_size
; mov ecx, (disasm_y_pos-1)*10000h + (disasm_y_size+1)
; mcall
;
; @@@@@ NOW:
draw_disasm:
 
.redraw:
mov eax, [disasm_start_pos]
mov [disasm_cur_pos], eax
and [disasm_cur_str], 0
 
.loop:
mov eax, [disasm_cur_pos]
call find_symbol
jc .nosymb
mov ebx, [disasm_cur_str]
imul ebx, 10
push ebx
lea ecx, [ebx+disasm_y_pos-1]
shl ecx, 16
mov cl, 11
; setting up background color for disassembled text
mov edx, COLOR_BG_NORMAL
;mov ebx, data_x_pos*10000h + data_x_size
;push 13
;pop eax
; draw container rectangle/box with color COLOR_BG_NORMAL (was 0xFFFFFF - white)
mcall 13, data_x_pos*10000h+data_x_size
pop ebx
; copy color value from edx (COLOR_BG_NORMAL)
mov edi, edx
add ebx, (data_x_pos+6*2)*10000h+disasm_y_pos
mov edx, esi
 
@@:
lodsb
test al, al
jnz @b
mov byte [esi-1], ':'
sub esi, edx
; normal color
; was 0x40000000
mov ecx, (COLOR_TXT_NORMAL or 0x40000000)
mov al, 4
; draw a text string in the window with color COLOR_TXT_NORMAL in ecx
mcall
mov byte [esi+edx-1], 0
lea esi, [esi*3]
movzx ecx, bx
shr ebx, 16
lea ebx, [ebx+esi*2]
shl ecx, 16
mov cl, 10
imul ebx, 10001h
sub bx, data_x_pos+data_x_size
neg bx
mov al, 13
; copy color value from edi
mov edx, edi
; draw container rectangle/box for disassembled text, color in edx
mcall
inc [disasm_cur_str]
cmp [disasm_cur_str], disasm_height
jae .loopend
 
.nosymb:
push [disasm_cur_pos]
call disasm_instr
pop ebp
jc .loopend
; setting up colors
; was 'xor esi, esi' - default color: black
mov esi, COLOR_TXT_NORMAL
; was 0xFFFFFF - default background: white
mov edx, COLOR_BG_NORMAL
mov ebx, data_x_pos*10000h + data_x_size
mov ecx, [disasm_cur_str]
imul ecx, 10*10000h
add ecx, (disasm_y_pos-1)*10000h + 10
mov eax, ebp
pushad
call find_enabled_breakpoint
popad
jnz .nored
; setting up background color for breakpoint
; was 0xFF0000 - red
mov edx, COLOR_BG_BREAKPOINT
 
.nored:
mov eax, [_eip]
cmp eax, ebp
jnz .noblue
; setting up background color for selected text
; (current running instruction)
; was 0x0000FF - blue
mov edx, COLOR_BG_SELECTED
; setting up selected text color
; (current running instruction)
; was 0xFFFFFF - white
mov esi, COLOR_TXT_SELECTED
 
.noblue:
;push 13
;pop eax
; draw container rectangle/box for disassembled text
; color in edx
mcall 13
;mov al, 47
;mov ebx, 80100h
mov edx, [disasm_cur_str]
imul edx, 10
add edx, data_x_pos*10000h + disasm_y_pos
;mov ecx, ebp
; draw a number in the window, color in esi
mcall 47, 80100h, ebp
;mov al, 4
lea ebx, [edx+8*6*10000h]
; copy color value from esi
mov ecx, esi
push 2
pop esi
mov edx, aColon
; draw a text string in the window, color in ecx
mcall 4
push 9
pop edi
lea edx, [ebx+2*6*10000h]
mov esi, ecx
mov ecx, ebp
sub ecx, [disasm_start_pos]
add ecx, disasm_buffer
 
.drawhex:
;mov al, 47
;mov ebx, 20101h
; draw a number in the window, color in esi
mcall 47, 20101h
add edx, 6*3*10000h
inc ecx
inc ebp
cmp ebp, [disasm_cur_pos]
jae .hexdone
dec edi
jnz .drawhex
push esi
mov esi, [disasm_cur_pos]
dec esi
cmp esi, ebp
pop esi
jbe .drawhex
;mov al, 4
lea ebx, [edx-6*10000h]
; copy color value from esi
mov ecx, esi
push 3
pop esi
mov edx, aDots
; draw a text string in the window, color in ecx
mcall 4
; copy color value from ecx
mov esi, ecx
 
.hexdone:
xor eax, eax
mov edi, disasm_string
mov edx, edi
or ecx, -1
repnz scasb
not ecx
dec ecx
xchg ecx, esi
mov ebx, [disasm_cur_str]
imul ebx, 10
add ebx, (data_x_pos+6*40)*10000h+disasm_y_pos
;mov al, 4
; draw a text string in the window, color in ecx
mcall 4
inc [disasm_cur_str]
cmp [disasm_cur_str], disasm_height
jb .loop
 
.loopend:
mov ecx, disasm_height
sub ecx, [disasm_cur_str]
jz @f
imul ecx, 10
inc ecx
mov eax, disasm_y_pos + disasm_y_size
sub eax, ecx
shl eax, 16
add ecx, eax
;push 13
;pop eax
;mov ebx, data_x_pos*65536 + data_x_size
; set backroung color for disassembly container
; was 0xFFFFFF - white
mov edx, COLOR_BG_NORMAL
; draw container rectangle/box with color COLOR_BG_NORMAL (in edx)
mcall 13, data_x_pos*65536+data_x_size
 
@@:
ret
 
;-----------------------------------------------------------------------------
 
; TODO: cleanup of this function, make some global labels local
update_disasm_eip:
; test if instruction at eip is showed
mov ecx, disasm_height
mov eax, [disasm_start_pos]
mov [disasm_cur_pos], eax
 
.l:
mov eax, [disasm_cur_pos]
call find_symbol
jc @f
dec ecx
jz .m
 
@@:
cmp [_eip], eax
jz draw_disasm.redraw
push ecx
call disasm_instr
pop ecx
jc .m
loop .l
 
.m:
 
update_disasm_eip_force:
mov eax, [_eip]
mov [disasm_start_pos], eax
 
update_disasm:
cmp [debuggee_pid], 0
jz .no
;push 69
;pop eax
;push 6
;pop ebx
;mov ecx, [debuggee_pid]
;mov edi, disasm_buffer
;mov edx, 256
;mov esi, [disasm_start_pos]
mcall 69, 6, [debuggee_pid], 256, [disasm_start_pos], disasm_buffer
cmp eax, -1
jnz @f
mov esi, read_mem_err
call put_message
 
.no:
xor eax, eax
 
@@:
mov [disasm_buf_size], eax
call restore_from_breaks
jmp draw_disasm.redraw
 
 
;-----------------------------------------------------------------------------
; Draw main window
 
draw_window:
; start window redraw
;push 12
;pop eax
;push 1
;pop ebx
mcall 12, 1
 
; define window
;xor eax, eax
;mov ebx, wnd_x_size
;mov ecx, wnd_y_size
;mov edx, 54FFFFFFh
mov edi, caption_str
; draw window with color in edx
; was 0x54FFFFFF - white background
mcall 0, wnd_x_size, wnd_y_size, (COLOR_BG_NORMAL or 0x54000000)
 
; clear unused areas
;mov al, 48
;push 4
;pop ebx
; get window skin height
mcall 48, 4
cmp eax, title_y_pos
jb @f
push registers_y_pos
pop eax
 
@@:
push registers_y_pos
pop ecx
push eax
sub ecx, eax
shl eax, 16
add ecx, eax
mov ebx, 5*10000h + (wnd_x_size-9)
;push 13
;pop eax
; color in edx for all rectangles (COLOR_BG_NORMAL)
; draw container rectangle/box for registers information region
mcall 13
mov ecx, (dump_y_pos+dump_y_size)*10000h + (disasm_y_pos-dump_y_pos-dump_y_size)
; draw container rectangle/box for dump memory region
mcall
mov ecx, (disasm_y_pos-1+disasm_y_size)*10000h + (messages_y_pos-disasm_y_pos+1-disasm_y_size)
; draw container rectangle/box for disassembled code region
mcall
mov ecx, (messages_y_pos+messages_y_size)*10000h + (wnd_y_size-messages_y_pos-messages_y_size-4)
; draw container rectangle/box for messages window region
mcall
mov ebx, 5*10000h + (data_x_pos-5)
pop ecx
imul ecx, 10001h
sub cx, wnd_y_size-4
neg cx
; draw container rectangle/box
mcall
mov ebx, (data_x_pos+data_x_size)*10000h + (wnd_x_size-data_x_pos-data_x_size-4)
; draw container rectangle/box
mcall
 
; messages frame
;mov al, 38
mov ebx, (messages_x_pos-2)*10000h + (messages_x_pos+messages_x_size+2)
push ebx
mov ecx, (messages_y_pos-2)*10001h
; setting up lines color
; was 'xor edx, edx' - black
mov edx, COLOR_LINE
; draw line, color in edx
mcall 38
mov ecx, (messages_y_pos+messages_y_size+2)*10001h
; draw line, color in edx
mcall
mov ebx, (messages_x_pos-2)*10001h
push ebx
mov ecx, (messages_y_pos-2)*10000h + (messages_y_pos+messages_y_size+2)
; draw line, color in edx
mcall
mov ebx, (messages_x_pos+messages_x_size+2)*10001h
push ebx
; draw line, color in edx
mcall
 
; command line frame
mov ecx, (cmdline_y_pos-2)*10000h + (cmdline_y_pos+cmdline_y_size+2)
pop ebx
; draw line, color in edx
mcall
pop ebx
; draw line, color in edx
mcall
pop ebx
mov ecx, (cmdline_y_pos+cmdline_y_size+2)*10001h
; draw line, color in edx
mcall
mov ecx, (cmdline_y_pos-2)*10001h
; draw line, color in edx
mcall
 
; registers frame
;push 13
;pop eax
mov ebx, (registers_x_pos-2)*10000h + (registers_x_size+4)
mov ecx, (registers_y_pos-2)*10000h + (registers_y_size+4)
; draw container rectangle/box for registers information window region
; color in edx
mcall 13
 
; messages
call draw_messages
 
; command line & cursor
call draw_cmdline
call draw_cursor
 
; title & registers & dump & disasm
;mov al, 38
mov ebx, (data_x_pos-2)*10001h
mov ecx, (title_y_pos+5)*10000h + (messages_y_pos-2)
; draw line, color in edx
mcall 38
mov ebx, (data_x_pos+data_x_size+2)*10001h
; draw line, color in edx
mcall
mov ebx, (data_x_pos-2)*10000h + (data_x_pos+data_x_size+2)
mov ecx, (dump_y_pos-3)*10001h
; draw line, color in edx
mcall
mov ecx, (disasm_y_pos-4)*10001h
; draw line, color in edx
mcall
 
; redraw whole window again
call redraw_title
call draw_registers
call draw_dump
call draw_disasm.redraw
 
; end of window redraw
;push 12
;pop eax
;push 2
;pop ebx
mcall 12, 2
ret
 
; vim: ft=fasm tabstop=4
 
/programs/develop/mtdbg/mtdbg.asm
10,267 → 10,24
dd i_param
dd 0
 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; GUI ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;-----------------------------------------------------------------------------
 
data_width equ 80
data_x_pos equ 12
data_x_size equ data_width*6
REG_MODE_CPU equ 1
REG_MODE_MMX equ 2
REG_MODE_SSE equ 3
REG_MODE_AVX equ 4
 
title_x_pos equ 30
title_y_pos equ 32
title_y_size equ 10
;-----------------------------------------------------------------------------
 
registers_x_pos equ data_x_pos
registers_y_pos equ (title_y_pos + title_y_size)
registers_y_size equ 30
include 'gui.inc' ; GUI routines
 
dump_y_pos equ (registers_y_pos + registers_y_size + 5)
dump_height equ 4
dump_y_size equ (dump_height*10)
;-----------------------------------------------------------------------------
; Find command in list
 
disasm_y_pos equ (dump_y_pos + dump_y_size + 4)
disasm_height equ 16
disasm_y_size equ (disasm_height*10)
 
messages_width equ data_width
messages_height equ 12
messages_x_pos equ data_x_pos
messages_y_pos equ (disasm_y_pos + disasm_y_size + 4)
messages_x_size equ messages_width*6
messages_y_size equ messages_height*10
 
cmdline_width equ data_width
cmdline_x_pos equ data_x_pos
cmdline_y_pos equ (messages_y_pos + messages_y_size + 10)
cmdline_x_size equ messages_x_size
cmdline_y_size equ 10
 
wnd_x_size equ (data_x_pos + messages_x_size + data_x_pos)
wnd_y_size equ (cmdline_y_pos + cmdline_y_size + data_x_pos)
 
start:
mcall 68, 11
mov edi, messages
mov ecx, messages_width*messages_height
mov al, ' '
rep stosb
xor eax, eax
mov [messages_pos], eax
mov [cmdline_len], eax
mov [cmdline_pos], eax
mov edi, needzerostart
mov ecx, (needzeroend-needzerostart+3)/4
rep stosd
mov esi, begin_str
call put_message_nodraw
; set event mask - default events and debugging events
push 40
pop eax
mov ebx, 0x107
mcall
; set debug messages buffer
mov ecx, dbgbufsize
mov dword [ecx], 256
xor ebx, ebx
mov [ecx+4], ebx
mov al, 69
mcall
mov esi, i_param
call skip_spaces
test al, al
jz dodraw
push esi
call draw_window
pop esi
call OnLoadInit
jmp waitevent
dodraw:
call draw_window
waitevent:
push 10
pop eax
mcall
cmp al, 9
jz debugmsg
dec eax
jz dodraw
dec eax
jz keypressed
dec eax
jnz waitevent
; button pressed - we have only one button (close)
push -1
pop eax
mcall
keypressed:
mov al, 2
mcall
shr eax, 8
cmp al, 8
jz .backspace
cmp al, 0xB0
jz .left
cmp al, 0xB3
jz .right
cmp al, 0x0D
jz .enter
cmp al, 0xB6
jz .del
cmp al, 0xB4
jz .home
cmp al, 0xB5
jz .end
cmp al, 0xB1
jz .down
cmp al, 0xB2
jz .up
cmp al, 0xD8
jz CtrlF7
cmp al, 0xD9
jz CtrlF8
cmp [cmdline_len], cmdline_width
jae waitevent
push eax
call clear_cmdline_end
pop eax
mov edi, cmdline
mov ecx, [cmdline_len]
add edi, ecx
lea esi, [edi-1]
sub ecx, [cmdline_pos]
std
rep movsb
cld
stosb
inc [cmdline_len]
call draw_cmdline_end
inc [cmdline_pos]
call draw_cursor
jmp waitevent
.backspace:
cmp [cmdline_pos], 0
jz waitevent
dec [cmdline_pos]
.delchar:
call clear_cmdline_end
mov edi, [cmdline_pos]
dec [cmdline_len]
mov ecx, [cmdline_len]
sub ecx, edi
add edi, cmdline
lea esi, [edi+1]
rep movsb
call draw_cmdline_end
call draw_cursor
jmp waitevent
.del:
mov eax, [cmdline_pos]
cmp eax, [cmdline_len]
jae waitevent
jmp .delchar
.left:
cmp [cmdline_pos], 0
jz waitevent
call hide_cursor
dec [cmdline_pos]
call draw_cursor
jmp waitevent
.right:
mov eax, [cmdline_pos]
cmp eax, [cmdline_len]
jae waitevent
call hide_cursor
inc [cmdline_pos]
call draw_cursor
jmp waitevent
.home:
call hide_cursor
and [cmdline_pos], 0
call draw_cursor
jmp waitevent
.end:
call hide_cursor
mov eax, [cmdline_len]
mov [cmdline_pos], eax
call draw_cursor
.up:
.down:
jmp waitevent
.enter:
mov ecx, [cmdline_len]
test ecx, ecx
jz waitevent
mov esi, cmdline
mov byte [esi+ecx], 0
and [cmdline_pos], 0
push esi
call clear_cmdline_end
call draw_cursor
pop esi
and [cmdline_len], 0
; skip leading spaces
call skip_spaces
cmp al, 0
jz waitevent
; now esi points to command
push esi
mov esi, prompt
call put_message_nodraw
pop esi
push esi
call put_message_nodraw
z1: mov esi, newline
call put_message
pop esi
push esi
call get_arg
mov [curarg], esi
pop edi
mov esi, commands
call find_cmd
mov eax, aUnknownCommand
jc .x11
; check command requirements
; flags field:
; &1: command may be called without parameters
; &2: command may be called with parameters
; &4: command may be called without loaded program
; &8: command may be called with loaded program
mov eax, [esi+8]
mov ecx, [curarg]
cmp byte [ecx], 0
jz .noargs
test byte [esi+16], 2
jz .x11
jmp @f
.noargs:
test byte [esi+16], 1
jz .x11
@@:
cmp [debuggee_pid], 0
jz .nodebuggee
mov eax, aAlreadyLoaded
test byte [esi+16], 8
jz .x11
jmp .x9
.nodebuggee:
mov eax, need_debuggee
test byte [esi+16], 4
jnz .x9
.x11:
xchg esi, eax
call put_message
.x10:
jmp waitevent
.x9:
call dword [esi+4]
jmp .x10
 
find_cmd:
; all commands are case-insensitive
push edi
 
.x4:
mov al, [edi]
cmp al, 0
280,12 → 37,15
cmp al, 'Z'
ja @f
or al, 20h
 
@@:
stosb
jmp .x4
 
; find command
.x5:
; find command
pop edi
 
.x6:
cmp dword [esi], 0
jz .x7
300,827 → 60,20
jz .x8
add esi, 17
jmp .x6
 
.x7:
stc
 
.x8:
ret
 
get_arg:
lodsb
cmp al, ' '
ja get_arg
mov byte [esi-1], 0
cmp al, 0
jnz skip_spaces
dec esi
skip_spaces:
lodsb
cmp al, 0
jz @f
cmp al, ' '
jbe skip_spaces
@@: dec esi
ret
 
clear_cmdline_end:
mov ebx, [cmdline_pos]
mov ecx, [cmdline_len]
sub ecx, ebx
push 13
pop eax
imul ebx, 6
imul ecx, 6
inc ecx
add ebx, cmdline_x_pos
shl ebx, 16
or ebx, ecx
mov ecx, cmdline_y_pos*10000h + cmdline_y_size
mov edx, 0xFFFFFF
mcall
ret
 
draw_cmdline:
xor ebx, ebx
jmp @f
draw_cmdline_end:
mov ebx, [cmdline_pos]
@@:
mov esi, [cmdline_len]
sub esi, ebx
push 4
pop eax
xor ecx, ecx
lea edx, [cmdline+ebx]
imul ebx, 6
add ebx, cmdline_x_pos
shl ebx, 16
or ebx, cmdline_y_pos+1
mcall
ret
 
put_message_nodraw:
; in: esi->ASCIZ message
mov edx, [messages_pos]
.m:
lea edi, [messages+edx]
.l:
lodsb
cmp al, 0
jz .done
call test_scroll
cmp al, 10
jz .newline
cmp al, '%'
jnz @f
cmp dword [esp], z1
jnz .format
@@:
stosb
inc edx
jmp .l
.newline:
push edx
mov ecx, messages_width
xor eax, eax
xchg eax, edx
div ecx
xchg eax, edx
pop edx
test eax, eax
jz .m
sub edx, eax
add edx, ecx
jmp .m
.done:
mov [messages_pos], edx
ret
.format:
; at moment all format specs must be %<digit>X
lodsb ; get <digit>
sub al, '0'
movzx ecx, al
lodsb
pop eax
pop ebp
push eax
; write number in ebp with ecx digits
dec ecx
shl ecx, 2
.writenibble:
push ecx
call test_scroll
pop ecx
mov eax, ebp
shr eax, cl
and al, 0xF
cmp al, 10
sbb al, 69h
das
stosb
inc edx
sub ecx, 4
jns .writenibble
jmp .l
 
test_scroll:
cmp edx, messages_width*messages_height
jnz .ret
push esi
mov edi, messages
lea esi, [edi+messages_width]
mov ecx, (messages_height-1)*messages_width/4
rep movsd
push eax
mov al, ' '
push edi
push messages_width
pop ecx
sub edx, ecx
rep stosb
pop edi
pop eax
pop esi
.ret: ret
 
put_message:
call put_message_nodraw
 
draw_messages:
push 13
pop eax
mov edx, 0xFFFFFF
mov ebx, messages_x_pos*10000h+messages_x_size
mov ecx, messages_y_pos*10000h+messages_y_size
mcall
mov edx, messages
push messages_width
pop esi
xor ecx, ecx
mov al, 4
mov ebx, messages_x_pos*10000h+messages_y_pos
@@:
mcall
add edx, esi
add ebx, 10
cmp edx, messages+messages_width*messages_height
jb @b
ret
 
draw_cursor:
push 38
pop eax
mov ecx, cmdline_y_pos*10001h+cmdline_y_size-1
mov ebx, [cmdline_pos]
imul ebx, 6
add ebx, cmdline_x_pos
mov edx, ebx
shl ebx, 16
or ebx, edx
xor edx, edx
mcall
ret
hide_cursor:
mov ebx, [cmdline_pos]
push 13
pop eax
imul ebx, 6
add ebx, cmdline_x_pos
shl ebx, 16
inc ebx
mov ecx, cmdline_y_pos*10000h + cmdline_y_size
mov edx, 0xFFFFFF
mcall
mov ebx, [cmdline_pos]
cmp ebx, [cmdline_len]
jae .ret
mov al, 4
xor ecx, ecx
lea edx, [cmdline+ebx]
imul ebx, 6
add ebx, cmdline_x_pos
shl ebx, 16
or ebx, cmdline_y_pos+1
push 1
pop esi
mcall
.ret:
ret
 
redraw_title:
push 13
pop eax
mov edx, 0xFFFFFF
mov ebx, title_x_pos*10000h + data_x_pos+data_x_size-title_x_pos
mov ecx, title_y_pos*10000h + title_y_size
mcall
draw_title:
mov al, 38
mov ebx, (data_x_pos-2)*10000h + title_x_pos-5
mov ecx, (title_y_pos+5)*10001h
xor edx, edx
mcall
push NoPrgLoaded_len
pop esi
cmp [debuggee_pid], 0
jz @f
mov esi, [prgname_len]
@@: imul ebx, esi, 6
add ebx, title_x_pos+4
shl ebx, 16
mov bx, data_x_pos+data_x_size-10-5-6*7
cmp [bSuspended], 0
jz @f
add ebx, 6
@@:
mcall
mov ebx, (data_x_pos+data_x_size-10+4)*0x10000 + data_x_pos+data_x_size+2
mcall
mov al, 4
mov ebx, title_x_pos*10000h+title_y_pos
xor ecx, ecx
mov edx, NoPrgLoaded_str
cmp [debuggee_pid], 0
jz @f
mov edx, [prgname_ptr]
@@:
mcall
cmp [debuggee_pid], 0
jz .nodebuggee
mov ebx, (data_x_pos+data_x_size-10-6*7)*10000h + title_y_pos
mov edx, aRunning
push 7
pop esi
cmp [bSuspended], 0
jz @f
add ebx, 6*10000h
mov edx, aPaused
dec esi
@@:
mcall
ret
.nodebuggee:
mov al, 38
mov ebx, (data_x_pos+data_x_size-10-6*7-5)*0x10000 + data_x_pos+data_x_size+2
mov ecx, (title_y_pos+5)*10001h
xor edx, edx
jmp @b
 
draw_register:
; in: esi->value, edx->string, ecx=string len, ebx=coord
push edx
push ecx
push esi
mov eax, esi
mov esi, ecx
; color
mov ecx, 40808080h
cmp [debuggee_pid], 0
jz .cd
cmp [bSuspended], 0
jz .cd
mov ecx, 40000000h
push edi
mov edi, [eax]
cmp dword [eax+oldcontext-context], edi
pop edi
jz .cd
mov ecx, 0x4000AA00
.cd:
push 4
pop eax
mcall
imul esi, 60000h
lea edx, [ebx+esi]
mov al, 47
mov ebx, 80101h
mov esi, ecx
pop ecx
mcall
lea ebx, [edx+60000h*18]
mov esi, ecx
pop ecx
pop edx
add edx, ecx
ret
draw_flag:
movzx edi, byte [edx+7]
bt [_eflags], edi
jc .on
or byte [edx], 20h
jmp .onoff
.on:
and byte [edx], not 20h
.onoff:
mov ecx, 40808080h
cmp [debuggee_pid], 0
jz .doit
cmp [bSuspended], 0
jz .doit
mov ecx, 40000000h
bt [_eflags], edi
lahf
bt dword [_eflags + oldcontext - context], edi
rcl ah, 1
test ah, 3
jp .doit
mov ecx, 0x4000AA00
.doit:
mov ah, 0
mov edi, 0xFFFFFF
mcall
ret
 
draw_registers:
push 13
pop eax
mov edx, 0xFFFFFF
mov ebx, data_x_pos*10000h + data_x_size
mov ecx, registers_y_pos*10000h + registers_y_size
mcall
redraw_registers:
mov edi, 0xFFFFFF
mov esi, _eax
push 4
pop ecx
mov edx, regs_strs
mov ebx, registers_x_pos*10000h+registers_y_pos
call draw_register
add esi, _ebx-_eax
call draw_register
add esi, _ecx-_ebx
call draw_register
add esi, _edx-_ecx
call draw_register
mov ebx, registers_x_pos*10000h+registers_y_pos+10
add esi, _esi-_edx
call draw_register
add esi, _edi-_esi
call draw_register
add esi, _ebp-_edi
call draw_register
add esi, _esp-_ebp
call draw_register
mov ebx, registers_x_pos*10000h+registers_y_pos+20
add esi, _eip-_esp
call draw_register
mov cl, 7
add esi, _eflags-_eip
call draw_register
mov al, 4
mov ecx, 808080h
cmp [debuggee_pid], 0
jz @f
cmp [bSuspended], 0
jz @f
xor ecx, ecx
@@:
mov edx, aColon
xor esi, esi
inc esi
mov ebx, (registers_x_pos+37*6)*10000h + registers_y_pos+20
mcall
mov edx, flags
@@:
add ebx, 2*6*10000h
call draw_flag
inc edx
cmp dl, flags_bits and 0xFF
jnz @b
ret
 
draw_dump:
push 13
pop eax
mov edx, 0xFFFFFF
mov ebx, data_x_pos*10000h + data_x_size
mov ecx, dump_y_pos*10000h + dump_y_size
mcall
redraw_dump:
; addresses
mov al, 47
mov ebx, 80100h
mov edx, data_x_pos*10000h + dump_y_pos
mov ecx, [dumppos]
mov edi, 0xFFFFFF
mov esi, 40808080h
cmp [debuggee_pid], 0
jz @f
cmp [bSuspended], 0
jz @f
mov esi, 40000000h
@@:
mcall
add ecx, 10h
add edx, 10
cmp dl, dump_y_pos + dump_y_size
jb @b
; hex dump of data
mov ecx, dumpdata
push ecx
xor ebx, ebx
mov edx, (data_x_pos+12*6)*10000h + dump_y_pos
cmp [dumpread], ebx
jz .hexdumpdone1
.hexdumploop1:
push ebx
mov ebx, 20101h
mcall
pop ebx
add edx, 3*6*10000h
inc ecx
inc ebx
test bl, 15
jz .16
test bl, 7
jnz @f
add edx, 2*6*10000h - 10 + 6*(3*10h+2)*10000h
.16:
add edx, 10 - 6*(3*10h+2)*10000h
@@:
cmp ebx, [dumpread]
jb .hexdumploop1
.hexdumpdone1:
mov al, 4
mov ecx, esi
xchg ebx, edx
push 2
pop esi
.hexdumploop2:
cmp edx, dump_height*10h
jae .hexdumpdone2
push edx
mov edx, aQuests
mcall
pop edx
add ebx, 3*6*10000h
inc edx
test dl, 15
jz .16x
test dl, 7
jnz .hexdumploop2
add ebx, 2*6*10000h - 10 + 6*(3*10h+2)*10000h
.16x:
add ebx, 10 - 6*(3*10h+2)*10000h
jmp .hexdumploop2
.hexdumpdone2:
dec esi
; colon, minus signs
mov ebx, (data_x_pos+8*6)*10000h + dump_y_pos
mov edx, aColon
@@:
mcall
add ebx, 10
cmp bl, dump_y_pos+dump_height*10
jb @b
mov ebx, (data_x_pos+(12+3*8)*6)*10000h + dump_y_pos
mov edx, aMinus
@@:
mcall
add ebx, 10
cmp bl, dump_y_pos+dump_height*10
jb @b
; ASCII data
mov ebx, (data_x_pos+(12+3*10h+2+2)*6)*10000h + dump_y_pos
pop edx
push dump_height*10h
.asciiloop:
push edx
cmp byte [edx], 20h
jae @f
mov edx, aPoint
@@:
mcall
pop edx
inc edx
add ebx, 6*10000h
dec dword [esp]
jz .asciidone
test byte [esp], 15
jnz .asciiloop
add ebx, 10 - 6*10h*10000h
jmp .asciiloop
.asciidone:
pop ecx
ret
 
redraw_disasm:
; push 13
; pop eax
; mov edx, 0xFFFFFF
; mov ebx, data_x_pos*10000h + data_x_size
; mov ecx, (disasm_y_pos-1)*10000h + (disasm_y_size+1)
; mcall
draw_disasm:
mov eax, [disasm_start_pos]
mov [disasm_cur_pos], eax
and [disasm_cur_str], 0
.loop:
mov eax, [disasm_cur_pos]
call find_symbol
jc .nosymb
mov ebx, [disasm_cur_str]
imul ebx, 10
push ebx
lea ecx, [ebx+disasm_y_pos-1]
shl ecx, 16
mov cl, 11
mov edx, 0xFFFFFF
mov ebx, data_x_pos*10000h + data_x_size
push 13
pop eax
mcall
pop ebx
mov edi, edx
add ebx, (data_x_pos+6*2)*10000h+disasm_y_pos
mov edx, esi
@@: lodsb
test al, al
jnz @b
mov byte [esi-1], ':'
sub esi, edx
mov ecx, 40000000h
mov al, 4
mcall
mov byte [esi+edx-1], 0
lea esi, [esi*3]
movzx ecx, bx
shr ebx, 16
lea ebx, [ebx+esi*2]
shl ecx, 16
mov cl, 10
imul ebx, 10001h
sub bx, data_x_pos+data_x_size
neg bx
mov al, 13
mov edx, edi
mcall
inc [disasm_cur_str]
cmp [disasm_cur_str], disasm_height
jae .loopend
.nosymb:
push [disasm_cur_pos]
call disasm_instr
pop ebp
jc .loopend
xor esi, esi ; default color: black
mov edx, 0xFFFFFF ; default background: white
mov ebx, data_x_pos*10000h + data_x_size
mov ecx, [disasm_cur_str]
imul ecx, 10*10000h
add ecx, (disasm_y_pos-1)*10000h + 10
mov eax, ebp
pushad
call find_enabled_breakpoint
popad
jnz .nored
mov edx, 0xFF0000 ; use background: red
.nored:
mov eax, [_eip]
cmp eax, ebp
jnz .noblue
mov edx, 0x0000FF ; use background: blue
mov esi, 0xFFFFFF ; on blue bgr, use white color
.noblue:
push 13
pop eax
mcall
mov al, 47
mov ebx, 80100h
mov edx, [disasm_cur_str]
imul edx, 10
add edx, data_x_pos*10000h + disasm_y_pos
mov ecx, ebp
mcall
mov al, 4
lea ebx, [edx+8*6*10000h]
mov ecx, esi
push 2
pop esi
mov edx, aColon
mcall
push 9
pop edi
lea edx, [ebx+2*6*10000h]
mov esi, ecx
mov ecx, ebp
sub ecx, [disasm_start_pos]
add ecx, disasm_buffer
.drawhex:
mov al, 47
mov ebx, 20101h
mcall
add edx, 6*3*10000h
inc ecx
inc ebp
cmp ebp, [disasm_cur_pos]
jae .hexdone
dec edi
jnz .drawhex
push esi
mov esi, [disasm_cur_pos]
dec esi
cmp esi, ebp
pop esi
jbe .drawhex
mov al, 4
lea ebx, [edx-6*10000h]
mov ecx, esi
push 3
pop esi
mov edx, aDots
mcall
mov esi, ecx
.hexdone:
xor eax, eax
mov edi, disasm_string
mov edx, edi
or ecx, -1
repnz scasb
not ecx
dec ecx
xchg ecx, esi
mov ebx, [disasm_cur_str]
imul ebx, 10
add ebx, (data_x_pos+6*40)*10000h+disasm_y_pos
mov al, 4
mcall
inc [disasm_cur_str]
cmp [disasm_cur_str], disasm_height
jb .loop
.loopend:
mov ecx, disasm_height
sub ecx, [disasm_cur_str]
jz @f
imul ecx, 10
inc ecx
mov eax, disasm_y_pos + disasm_y_size
sub eax, ecx
shl eax, 16
add ecx, eax
push 13
pop eax
mov ebx, data_x_pos*65536 + data_x_size
mov edx, 0xFFFFFF
mcall
@@:
ret
 
update_disasm_eip:
; test if instruction at eip is showed
mov ecx, disasm_height
mov eax, [disasm_start_pos]
mov [disasm_cur_pos], eax
.l:
mov eax, [disasm_cur_pos]
call find_symbol
jc @f
dec ecx
jz .m
@@:
cmp [_eip], eax
jz redraw_disasm
push ecx
call disasm_instr
pop ecx
jc .m
loop .l
.m:
update_disasm_eip_force:
mov eax, [_eip]
mov [disasm_start_pos], eax
update_disasm:
cmp [debuggee_pid], 0
jz .no
push 69
pop eax
push 6
pop ebx
mov ecx, [debuggee_pid]
mov edi, disasm_buffer
mov edx, 256
mov esi, [disasm_start_pos]
mcall
cmp eax, -1
jnz @f
mov esi, read_mem_err
call put_message
.no:
xor eax, eax
@@:
mov [disasm_buf_size], eax
call restore_from_breaks
jmp redraw_disasm
 
draw_window:
; start redraw
push 12
pop eax
push 1
pop ebx
mcall
; define window
xor eax, eax
mov ebx, wnd_x_size
mov ecx, wnd_y_size
mov edx, 54FFFFFFh
mov edi, caption_str
mcall
; clear unused areas
mov al, 48
push 4
pop ebx
mcall
cmp eax, title_y_pos
jb @f
push registers_y_pos
pop eax
@@:
push registers_y_pos
pop ecx
push eax
sub ecx, eax
shl eax, 16
add ecx, eax
mov ebx, 5*10000h + (wnd_x_size-9)
push 13
pop eax
mcall
mov ecx, (registers_y_pos+registers_y_size)*10000h + (dump_y_pos-registers_y_pos-registers_y_size)
mcall
mov ecx, (dump_y_pos+dump_y_size)*10000h + (disasm_y_pos-dump_y_pos-dump_y_size)
mcall
mov ecx, (disasm_y_pos-1+disasm_y_size)*10000h + (messages_y_pos-disasm_y_pos+1-disasm_y_size)
mcall
mov ecx, (messages_y_pos+messages_y_size)*10000h + (wnd_y_size-messages_y_pos-messages_y_size-4)
mcall
mov ebx, 5*10000h + (data_x_pos-5)
pop ecx
imul ecx, 10001h
sub cx, wnd_y_size-4
neg cx
mcall
mov ebx, (data_x_pos+data_x_size)*10000h + (wnd_x_size-data_x_pos-data_x_size-4)
mcall
; messages frame
mov al, 38
mov ebx, (messages_x_pos-2)*10000h + (messages_x_pos+messages_x_size+2)
push ebx
mov ecx, (messages_y_pos-2)*10001h
xor edx, edx
mcall
mov ecx, (messages_y_pos+messages_y_size+2)*10001h
mcall
mov ebx, (messages_x_pos-2)*10001h
push ebx
mov ecx, (messages_y_pos-2)*10000h + (messages_y_pos+messages_y_size+2)
mcall
mov ebx, (messages_x_pos+messages_x_size+2)*10001h
push ebx
mcall
; command line frame
mov ecx, (cmdline_y_pos-2)*10000h + (cmdline_y_pos+cmdline_y_size+2)
pop ebx
mcall
pop ebx
mcall
pop ebx
mov ecx, (cmdline_y_pos+cmdline_y_size+2)*10001h
mcall
mov ecx, (cmdline_y_pos-2)*10001h
mcall
; messages
call draw_messages
; command line & cursor
call draw_cmdline
call draw_cursor
; title & registers & dump & disasm
mov al, 38
mov ebx, (data_x_pos-2)*10001h
mov ecx, (title_y_pos+5)*10000h + (messages_y_pos-2)
mcall
mov ebx, (data_x_pos+data_x_size+2)*10001h
mcall
mov ebx, (data_x_pos-2)*10000h + (data_x_pos+data_x_size+2)
mov ecx, (dump_y_pos-3)*10001h
mcall
mov ecx, (disasm_y_pos-4)*10001h
mcall
call redraw_title
call draw_registers
call draw_dump
call redraw_disasm
; end redraw
push 12
pop eax
push 2
pop ebx
mcall
ret
 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; DEBUGGING ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
;-----------------------------------------------------------------------------
; Help event
 
OnHelp:
mov esi, help_msg
mov edi, [curarg]
1130,43 → 83,50
call find_cmd
jc .nocmd
mov esi, [esi+12]
 
.x:
jmp put_message
 
.nocmd:
mov esi, aUnknownCommand
jmp .x
 
;-----------------------------------------------------------------------------
; Quit event
OnQuit:
push -1
pop eax
mcall
mcall -1
 
;-----------------------------------------------------------------------------
; Working with debug context
 
get_new_context:
mov esi, context
mov edi, oldcontext
mov ecx, 10
rep movsd
 
get_context:
push 1
pop ebx
push 69
pop eax
mov ecx, [debuggee_pid]
mov esi, context
push 28h
pop edx
mcall
;push 1
;pop ebx
;push 69
;pop eax
;mov ecx, [debuggee_pid]
;mov esi, context
;push 28h
;pop edx
mcall 69, 1, [debuggee_pid], 28h, context
ret
 
set_context:
push 2
pop ebx
push 69
pop eax
mov ecx, [debuggee_pid]
mov esi, context
push 28h
pop edx
mcall
;push 2
;pop ebx
;push 69
;pop eax
;mov ecx, [debuggee_pid]
;mov esi, context
;push 28h
;pop edx
mcall 69, 2, [debuggee_pid], 28h, context
ret
 
get_dump:
1178,23 → 138,26
push edi
rep stosb
pop edi
mov ecx, [debuggee_pid]
mov al, 69
push 6
pop ebx
mcall
;mov ecx, [debuggee_pid]
;mov al, 69
;push 6
;pop ebx
mcall 69, 6, [debuggee_pid]
cmp eax, -1
jnz @f
mov esi, read_mem_err
call put_message
xor eax, eax
 
@@:
mov [edi-8], eax
; call restore_from_breaks
; ret
 
; in: edi=buffer,eax=size,esi=address
restore_from_breaks:
; in: edi=buffer,eax=size,esi=address
mov ebx, breakpoints
 
@@:
test byte [ebx+4], 1
jz .cont ; ignore invalid
1206,6 → 169,7
jae .cont
mov dl, [ebx+5]
mov [edi+ecx], dl
 
.cont:
add ebx, 6
cmp ebx, breakpoints+breakpoints_n*6
1212,12 → 176,17
jb @b
ret
 
;-----------------------------------------------------------------------------
; Load executable event
 
OnLoad:
mov esi, [curarg]
 
OnLoadInit:
mov edi, loadname
or [prgname_len], -1
mov [prgname_ptr], edi
 
.copyname:
lodsb
stosb
1226,6 → 195,7
jnz @f
or [prgname_len], -1
mov [prgname_ptr], edi
 
@@:
cmp al, ' '
ja .copyname
1232,10 → 202,11
mov byte [edi-1], 0
and [load_params], 0
dec esi
call skip_spaces
call get_arg.skip_spaces
cmp al, 0
jz @f
mov [load_params], esi
 
@@:
and [dumppos], 0
mov ecx, [symbols]
1243,20 → 214,23
mcall 68, 13
and [symbols], 0
and [num_symbols], 0
 
; TODO: make it local
do_reload:
push 18
pop eax
push 7
pop ebx
mcall
;push 18
;pop eax
;push 7
;pop ebx
mcall 18, 7
mov [dbgwnd], eax
xchg ecx, eax
push 70
pop eax
mov ebx, fn70_load_block
mcall
;push 70
;pop eax
;mov ebx, fn70_load_block
mcall 70, fn70_load_block
test eax, eax
jns .load_ok
 
.load_err:
push eax
mov esi, load_err_msg
1268,6 → 242,7
mov esi, [load_err_msgs+eax*4]
test esi, esi
jnz put_message
 
.unk_err:
mov esi, unk_err_msg
inc eax
1274,6 → 249,7
push eax
call put_message_nodraw
jmp draw_messages
 
.load_ok:
mov [debuggee_pid], eax
mov [bSuspended], 1
1282,16 → 258,18
mov edi, oldcontext
mov ecx, 10
rep movsd
 
; activate debugger window
pop ecx
mov bl, 3
push 18
pop eax
mcall
;mov bl, 3
;push 18
;pop eax
mcall 18, 3
call redraw_title
call redraw_registers
call draw_registers.redraw
; read and draw dump of memory
call get_dump
call redraw_dump
call draw_dump.redraw
call update_disasm_eip_force
mov esi, load_succ_msg
push [debuggee_pid]
1301,6 → 279,7
mov esi, loadname
mov edi, symbolsfile
push edi
 
@@:
lodsb
stosb
1307,6 → 286,7
test al, al
jnz @b
lea ecx, [edi-1]
 
@@:
dec edi
cmp edi, symbolsfile
1316,6 → 296,7
cmp byte [edi], '.'
jnz @b
mov ecx, edi
 
@@:
mov dword [ecx], '.dbg'
mov byte [ecx+4], 0
1322,10 → 303,12
pop esi
mov ebp, esi
call OnLoadSymbols.silent
; now test for packed progs
cmp [disasm_buf_size], 100h
jz @f
ret
 
@@:
mov esi, mxp_nrv_sig
mov ebp, disasm_buffer
1339,6 → 322,7
repz cmpsb
mov esi, mxp_nrv_name
jz .packed
 
.not_mxp_nrv:
mov esi, mxp_sig
mov edi, ebp
1346,6 → 330,7
repz cmpsb
mov esi, mxp_name
jz .packed
 
.not_mxp:
mov esi, mxp_lzo_sig1
mov edi, ebp
1363,6 → 348,7
repz cmpsb
mov esi, mxp_lzo_name
jz .packed
 
.not_mxp_lzo:
mov esi, mtappack_name
cmp dword [ebp], 0xBF5E246A
1373,6 → 359,7
jnz .not_mtappack1
cmp byte [ebp+12h], 0xE9
jz .packed
 
.not_mtappack1:
cmp word [ebp+8], 0xB957
jnz .not_mtappack
1380,18 → 367,22
jnz .not_mtappack2
cmp byte [ebp+17h], 0xE9
jz .packed
 
.not_mtappack2:
cmp dword [ebp+14], 0x5F8DA4F3
jnz .not_mtappack3
cmp word [ebp+18], 0xE9FC
jz .packed
 
.not_mtappack3:
cmp word [ebp+14], 0xA4F3
jnz .not_mtappack
cmp byte [ebp+15h], 0xE9
jz .packed
 
.not_mtappack:
ret
 
.packed:
push esi
mov esi, aPacked1
1401,15 → 392,16
mov esi, aPacked2
call put_message
call hide_cursor
push 40
pop eax
push 7
pop ebx
mcall
;push 40
;pop eax
;push 7
;pop ebx
mcall 40, 7
 
.wait:
push 10
pop eax
mcall
;push 10
;pop eax
mcall 10
dec eax
jz .redraw
dec eax
1416,10 → 408,12
jz .key
or eax, -1
mcall
 
.redraw:
call draw_window
call hide_cursor
jmp .wait
 
.key:
mov al, 2
mcall
1433,19 → 427,21
jz .no
cmp ah, 'N'
jnz .wait
 
.no:
push 40
pop eax
mov ebx, 0x107
mcall
;push 40
;pop eax
;mov ebx, 0x107
mcall 40, 0x107
call draw_cursor
mov esi, aN_str
jmp put_message
 
.yes:
push 40
pop eax
mov ebx, 0x107
mcall
;push 40
;pop eax
;mov ebx, 0x107
mcall 40, 0x107
call draw_cursor
mov esi, aY_str
call put_message
1452,6 → 448,9
call OnUnpack
ret
 
;-----------------------------------------------------------------------------
; Searching signatures
 
mxp_nrv_sig:
xor eax, eax
mov ecx, 0x95 ; 0xA1 for programs with parameters
1466,6 → 465,7
pop esi
add esi, [eax]
xor edi, edi
 
mxp_nrv_sig_size = $ - mxp_nrv_sig
 
mxp_sig:
1484,6 → 484,7
push 0
push 8
call $+0x25
 
mxp_sig_size = $ - mxp_sig
 
mxp_lzo_sig1:
1503,7 → 504,9
xor edi, edi
cmp byte [ebx], 11h
jbe $+0x1A
 
mxp_lzo_sig1_size = $ - mxp_lzo_sig1
 
mxp_lzo_sig2:
xor eax, eax
mov ebp, 0FFh
1517,8 → 520,12
jmp dword [eax+20h]
mov ebx, [eax+20h]
add ebx, [eax]
 
mxp_lzo_sig2_size = $ - mxp_lzo_sig2
 
;-----------------------------------------------------------------------------
; Reload executable event
 
OnReload:
cmp [debuggee_pid], 0
jnz terminate_reload
1526,16 → 533,24
cmp byte [loadname], 0
jnz do_reload
jz put_message
 
; TODO: make it local
terminate_reload:
mov [bReload], 1
 
;-----------------------------------------------------------------------------
; Terminate process event
 
OnTerminate:
mov ecx, [debuggee_pid]
push 8
pop ebx
push 69
pop eax
mcall
;mov ecx, [debuggee_pid]
;push 8
;pop ebx
;push 69
;pop eax
mcall 69, 8, [debuggee_pid]
ret
;-----------------------------------------------------------------------------
; Suspend process event
 
AfterSuspend:
mov [bSuspended], 1
1542,30 → 557,35
call get_new_context
call get_dump
call redraw_title
call redraw_registers
call redraw_dump
call draw_registers.redraw
call draw_dump.redraw
call update_disasm_eip
ret
 
OnSuspend:
mov ecx, [debuggee_pid]
push 4
pop ebx
push 69
pop eax
mcall
;mov ecx, [debuggee_pid]
;push 4
;pop ebx
;push 69
;pop eax
mcall 69, 4, [debuggee_pid]
call AfterSuspend
mov esi, aSuspended
jmp put_message
 
;-----------------------------------------------------------------------------
; Resume process event
 
DoResume:
mov ecx, [debuggee_pid]
push 5
pop ebx
push 69
pop eax
mcall
;mov ecx, [debuggee_pid]
;push 5
;pop ebx
;push 69
;pop eax
mcall 69, 5, [debuggee_pid]
mov [bSuspended], 0
ret
 
OnResume:
mov esi, [curarg]
cmp byte [esi], 0
1582,8 → 602,10
jnc GoOn
mov esi, aBreakpointLimitExceeded
call put_message
 
.ret:
ret
 
GoOn:
; test for enabled breakpoint at eip
mov eax, [_eip]
1601,23 → 623,28
and byte [_eflags+1], not 1
call DoResume
ret
 
.nobreak:
call DoResume
call redraw_title
call redraw_registers
call redraw_dump
call draw_registers.redraw
call draw_dump.redraw
ret
 
;-----------------------------------------------------------------------------
; Detach process event
 
OnDetach:
mov ecx, [debuggee_pid]
push 3
pop ebx
push 69
pop eax
mcall
;mov ecx, [debuggee_pid]
;push 3
;pop ebx
;push 69
;pop eax
mcall 69, 3, [debuggee_pid]
and [debuggee_pid], 0
call redraw_title
call redraw_registers
call redraw_dump
call draw_registers.redraw
call draw_dump.redraw
call free_symbols
mov esi, aContinued
jmp put_message
1643,7 → 670,9
push esi
call get_dump
jmp exception.done
@@: test eax, eax
 
@@:
test eax, eax
jz .notint1
; if exception is result of single step, simply ignore it and continue
test dword [esi], 0xF
1656,6 → 685,7
rep movsd
call DoResume
jmp dbgmsgend
 
.notint1:
; in other case, work as without temp_break
lodsd
1662,11 → 692,15
push esi
push eax
jmp exception.4
 
.notour:
 
; TODO: split it out
debugmsg:
neg [dbgbufsize]
mov esi, dbgbuf
 
; TODO: make it local
dbgmsgstart:
lodsd
; push eax esi
1687,6 → 721,8
and [_eflags], not 10100h ; clear TF,RF
call set_context
pop esi
 
; TODO: WTF? Need for meaning label names
.5:
push esi
call get_dump
1693,6 → 729,7
pop esi
lodsd
xor ecx, ecx
 
.6:
bt eax, ecx
jnc .7
1705,6 → 742,7
mov esi, aBreakStop
call put_message_nodraw
popad
 
.7:
inc ecx
cmp cl, 4
1711,6 → 749,8
jb .6
push esi
jmp exception.done_draw
 
; TODO: make it local
terminated:
push esi
mov esi, terminated_msg
1727,6 → 767,7
jnz exception.done
call free_symbols
jmp exception.done
 
exception:
mov [bSuspended], 1
cmp [bAfterGo], 0
1737,6 → 778,8
call get_new_context
and [_eflags], not 10100h ; clear TF,RF
call set_context
 
; TODO: fix for useful name
.4:
call get_dump
pop eax
1746,17 → 789,17
jnz .notdbg
; check for 0xCC byte at eip
push 0
push 69
;push 69
;pop eax
;push 6
;pop ebx
;mov ecx, [debuggee_pid]
;mov edi, esp
;mov esi, [_eip]
;push 1
;pop edx
mcall 69, 6, [debuggee_pid], 1, [_eip], esp
pop eax
push 6
pop ebx
mov ecx, [debuggee_pid]
mov edi, esp
mov esi, [_eip]
push 1
pop edx
mcall
pop eax
cmp al, 0xCC
jnz .notdbg
; this is either dbg breakpoint or int3 cmd in debuggee
1772,6 → 815,7
pop ecx
call clear_breakpoint
jmp .done
 
.user_int3:
mov eax, [_eip]
inc [_eip]
1780,23 → 824,28
call set_context
mov esi, aUserBreak
jmp .put_msg_eax
 
.notdbg:
mov esi, aException
 
.put_msg_eax:
call put_message_nodraw
 
.done_draw:
call draw_messages
 
.done:
push 18
pop eax
push 3
pop ebx
mov ecx, [dbgwnd]
mcall ; activate dbg window
;push 18
;pop eax
;push 3
;pop ebx
;mov ecx, [dbgwnd]
mcall 18, 3, [dbgwnd] ; activate dbg window
call redraw_title
call redraw_registers
call redraw_dump
call draw_registers.redraw
call draw_dump.redraw
call update_disasm_eip
 
dbgmsgend:
pop esi
mov ecx, [dbgbuflen]
1809,15 → 858,20
jnz @f
mov [bReload], 0
call do_reload
 
@@:
jmp waitevent
 
; TODO: make it local
CtrlF7:
cmp [debuggee_pid], 0
jz .no
call OnStep
 
.no:
jmp waitevent
 
; TODO: make it local
CtrlF8:
cmp [debuggee_pid], 0
jz CtrlF7.no
1824,9 → 878,26
call OnProceed
jmp CtrlF7.no
 
;-----------------------------------------------------------------------------
; Step execution event
 
;Here we get [<number>] argument at do step <number> times
OnStep:
cmp [bSuspended], 0
jz .running
cmp [step_num], 0
jg .stepone
mov esi, [curarg]
cmp byte [esi], 0
jz .stepone
call get_hex_number
jc .ret
cmp eax, 0 ; check if lesser or equal than 0
jle .ret
mov [step_num], eax
mov [curarg], 0
 
.stepone:
call get_context
or byte [_eflags+1], 1 ; set TF
call set_context
1837,18 → 908,19
jnz @f
cmp byte [edi+5], 0xCD
jz .int
 
@@:
push 0
push 69
pop eax
push 6
pop ebx
mov ecx, [debuggee_pid]
push 3
pop edx
mov edi, esp
mov esi, [_eip]
mcall
;push 69
;pop eax
;push 6
;pop ebx
;mov ecx, [debuggee_pid]
;push 3
;pop edx
;mov edi, esp
;mov esi, [_eip]
mcall 69, 6, [debuggee_pid], 3, [_eip], esp
cmp eax, edx
pop eax
jnz .doit
1858,6 → 930,7
jz .syscall
cmp ax, 0x340F
jz .sysenter
 
; resume process
.doit:
call GoOn
1864,16 → 937,28
cmp [bAfterGo], 0
jz @f
mov [bAfterGo], 2
 
@@:
mov eax, [step_num]
dec eax
cmp eax, 0
jle .ret
mov [step_num], eax
jmp .stepone
 
.ret:
mov [step_num], 0
ret
.sysenter: ; return address is [ebp-4]
 
; return address is [ebp-4]
.sysenter:
push 0
push 69
pop eax
;push 69
;pop eax
inc edx ; read 4 bytes
mov esi, [_ebp]
sub esi, 4
mcall
mcall 69
cmp eax, edx
pop eax
jnz .syscall
1882,13 → 967,16
call set_context
pop eax
jmp @f
 
.syscall:
and byte [_eflags+1], not 1 ; clear TF - avoid system halt (!)
call set_context
 
.int:
mov eax, [_eip]
inc eax
inc eax
 
@@:
push eax
call find_enabled_breakpoint
1898,17 → 986,35
mov bl, 5
call add_breakpoint
jmp .doit
 
.running:
mov esi, aRunningErr
jmp put_message
 
;-----------------------------------------------------------------------------
; Proceed process event
 
OnProceed:
cmp [bSuspended], 0
jz OnStep.running
cmp [proc_num], 0
jg .procone
mov esi, [curarg]
cmp byte [esi], 0
jz .procone
call get_hex_number
jc .ret
cmp eax, 0 ; check if lesser than 0
jle .ret
mov [proc_num], eax
mov [curarg], 0
 
.procone:
mov esi, [_eip]
 
@@:
call get_byte_nobreak
jc OnStep
jc OnStep.stepone
inc esi
; skip prefixes
call is_prefix
1917,17 → 1023,23
jnz @f
add esi, 4
jmp .doit
@@: ; A4,A5 = movs, A6,A7=cmps
 
; A4,A5 = movs; A6,A7 = cmps
@@:
cmp al, 0xA4
jb @f
cmp al, 0xA8
jb .doit
@@: ; AA,AB=stos, AC,AD=lods, AE,AF=scas
 
; AA,AB = stos; AC,AD = lods; AE,AF = scas
@@:
cmp al, 0xAA
jb @f
cmp al, 0xB0
jb .doit
@@: ; E0=loopnz,E1=loopz,E2=loop
 
; E0 = loopnz; E1 = loopz; E2 = loop
@@:
cmp al, 0xE0
jb .noloop
cmp al, 0xE2
1934,16 → 1046,18
ja .noloop
inc esi
jmp .doit
.noloop: ; FF /2 = call
 
; FF /2 = call
.noloop:
cmp al, 0xFF
jnz OnStep
jnz OnStep.stepone
call get_byte_nobreak
jc OnStep
jc OnStep.stepone
inc esi
mov cl, al
and al, 00111000b
cmp al, 00010000b
jnz OnStep
jnz OnStep.stepone
; skip instruction
mov al, cl
and eax, 7
1953,38 → 1067,56
cmp al, 4
jnz @f
inc esi
 
@@:
inc esi
dec cl
jz @f
add esi, 3
 
@@:
jmp .doit
 
.mod0:
cmp al, 4
jnz @f
call get_byte_nobreak
jc OnStep
jc OnStep.stepone
inc esi
and al, 7
 
@@:
cmp al, 5
jnz .doit
add esi, 4
 
.doit:
; insert one-shot breakpoint at esi and resume
call get_byte_nobreak
jc OnStep
jc OnStep.stepone
mov eax, esi
call find_enabled_breakpoint
jz .ret
jz @f
mov eax, esi
mov bl, 5
call add_breakpoint
jmp OnStep.doit
 
@@:
mov eax, [proc_num]
dec eax
cmp eax, 0
jle .ret
mov [proc_num], eax
jmp .procone
 
.ret:
mov [proc_num], 0
ret
 
;-----------------------------------------------------------------------------
; Read next byte of machine code
 
get_byte_nobreak:
mov eax, esi
call find_enabled_breakpoint
1992,333 → 1124,32
mov al, [edi+5]
clc
ret
.nobreak:
push 69
pop eax
push 6
pop ebx
mov ecx, [debuggee_pid]
;push 69
;pop eax
;push 6
;pop ebx
;mov ecx, [debuggee_pid]
xor edx, edx
push edx
inc edx
mov edi, esp
mcall
mcall 69, 6, [debuggee_pid]
dec eax
clc
jz @f
stc
@@: pop eax
ret
 
is_prefix:
cmp al, 0x64 ; fs:
jz .ret
cmp al, 0x65 ; gs:
jz .ret
cmp al, 0x66 ; use16/32
jz .ret
cmp al, 0x67 ; addr16/32
jz .ret
cmp al, 0xF0 ; lock
jz .ret
cmp al, 0xF2 ; repnz
jz .ret
cmp al, 0xF3 ; rep(z)
jz .ret
cmp al, 0x2E ; cs:
jz .ret
cmp al, 0x36 ; ss:
jz .ret
cmp al, 0x3E ; ds:
jz .ret
cmp al, 0x26 ; es:
.ret: ret
 
token_end equ 1
token_reg equ 2
token_hex equ 3
token_add equ 4
token_sub equ 5
token_mul equ 6
token_div equ 7
token_lp equ 8
token_rp equ 9
token_err equ -1
 
is_hex_digit:
cmp al, '0'
jb .no
cmp al, '9'
jbe .09
cmp al, 'A'
jb .no
cmp al, 'F'
jbe .AF
cmp al, 'a'
jb .no
cmp al, 'f'
jbe .af
.no:
stc
ret
.09:
sub al, '0'
; clc
ret
.AF:
sub al, 'A'-10
; clc
ret
.af:
sub al, 'a'-10
; clc
ret
 
find_reg:
mov edi, reg_table
.findreg:
movzx ecx, byte [edi]
stc
jecxz .regnotfound
inc edi
push esi edi ecx
@@:
lodsb
or al, 20h
scasb
loopz @b
pop ecx edi esi
lea edi, [edi+ecx+1]
jnz .findreg
movzx edi, byte [edi-1]
add esi, ecx
.regnotfound:
ret
 
expr_get_token:
lodsb
cmp al, 0
jz .end_token
cmp al, ' '
jbe expr_get_token
cmp al, '+'
jz .add
cmp al, '-'
jz .sub
cmp al, '*'
jz .mul
cmp al, '/'
jz .div
cmp al, '('
jz .lp
cmp al, ')'
jnz .notsign
.rp:
mov al, token_rp
ret
.div:
mov al, token_div
ret
.end_token:
mov al, token_end
ret
.add:
mov al, token_add
ret
.sub:
mov al, token_sub
ret
.mul:
mov al, token_mul
ret
.lp:
mov al, token_lp
ret
.notsign:
dec esi
call find_reg
jc .regnotfound
mov al, token_reg
ret
.regnotfound:
; test for symbol
push esi
@@:
lodsb
cmp al, ' '
ja @b
push eax
mov byte [esi], 0
xchg esi, [esp+4]
call find_symbol_name
mov edi, eax
pop eax
xchg esi, [esp]
mov byte [esi], al
jc @f
add esp, 4
mov al, token_hex
ret
@@:
pop esi
; test for hex number
xor ecx, ecx
xor edi, edi
xor eax, eax
@@:
lodsb
call is_hex_digit
jc @f
shl edi, 4
or edi, eax
inc ecx
jmp @b
@@:
dec esi
jecxz .err
cmp ecx, 8
ja .err
mov al, token_hex
ret
.err:
mov al, token_err
mov esi, aParseError
ret
 
expr_read2:
cmp al, token_hex
jz .hex
cmp al, token_reg
jz .reg
cmp al, token_lp
jz .lp
mov al, token_err
mov esi, aParseError
ret
.hex:
mov ebp, edi
.ret:
jmp expr_get_token
.reg:
cmp edi, 24
jz .eip
sub edi, 4
jb .8lo
sub edi, 4
jb .8hi
sub edi, 8
jb .16
mov ebp, [_eax+edi*4]
jmp .ret
.16:
movzx ebp, word [_eax+(edi+8)*4]
jmp .ret
.8lo:
movzx ebp, byte [_eax+(edi+4)*4]
jmp .ret
.8hi:
movzx ebp, byte [_eax+(edi+4)*4+1]
jmp .ret
.eip:
mov ebp, [_eip]
jmp .ret
.lp:
call expr_get_token
call expr_read0
cmp al, token_err
jz @f
cmp al, token_rp
jz expr_get_token
mov al, token_err
mov esi, aParseError
@@: ret
include 'parser.inc'
 
expr_read1:
call expr_read2
.1:
cmp al, token_mul
jz .mul
cmp al, token_div
jz .div
ret
.mul:
push ebp
call expr_get_token
call expr_read2
pop edx
; ebp := edx*ebp
imul ebp, edx
jmp .1
.div:
push ebp
call expr_get_token
call expr_read2
pop edx
; ebp := edx/ebp
test ebp, ebp
jz .div0
push eax
xor eax, eax
xchg eax, edx
div ebp
xchg eax, ebp
pop eax
jmp .1
.div0:
mov al, token_err
mov esi, aDivByZero
ret
;-----------------------------------------------------------------------------
; Calculate expression event
 
expr_read0:
xor ebp, ebp
cmp al, token_add
jz .add
cmp al, token_sub
jz .sub
call expr_read1
.1:
cmp al, token_add
jz .add
cmp al, token_sub
jz .sub
ret
.add:
push ebp
call expr_get_token
call expr_read1
pop edx
; ebp := edx+ebp
add ebp, edx
jmp .1
.sub:
push ebp
call expr_get_token
call expr_read1
pop edx
; ebp := edx-ebp
xchg edx, ebp
sub ebp, edx
jmp .1
 
calc_expression:
; in: esi->expression
; out: CF=1 if error
; CF=0 and ebp=value if ok
call expr_get_token
call expr_read0
cmp al, token_end
jz .end
cmp al, token_err
jz @f
mov esi, aParseError
@@:
call put_message
stc
ret
.end:
clc
ret
 
OnCalc:
mov esi, [curarg]
call calc_expression
2327,9 → 1158,13
mov esi, calc_string
call put_message_nodraw
jmp draw_messages
.ret:
ret
 
;-----------------------------------------------------------------------------
; Dump memory event
 
OnDump:
mov esi, [curarg]
cmp byte [esi], 0
2336,16 → 1171,22
jnz .param
add [dumppos], dump_height*10h
jmp .doit
.param:
call calc_expression
jc .ret
mov [dumppos], ebp
 
.doit:
call get_dump
call redraw_dump
call draw_dump.redraw
 
.ret:
ret
 
;-----------------------------------------------------------------------------
; Dissassemble block of executable event
 
OnUnassemble:
mov esi, [curarg]
cmp byte [esi], 0
2353,6 → 1194,7
mov eax, [disasm_start_pos]
mov ecx, disasm_height
mov [disasm_cur_pos], eax
 
.l:
mov eax, [disasm_cur_pos]
call find_symbol
2359,6 → 1201,7
jc @f
dec ecx
jz .m
 
@@:
push ecx
call disasm_instr
2365,13 → 1208,16
pop ecx
jc .err
loop .l
 
.m:
mov eax, [disasm_cur_pos]
jmp .doit
 
.param:
call calc_expression
jc .ret
mov eax, ebp
 
.doit:
push eax
push [disasm_start_pos]
2382,32 → 1228,41
cmp [disasm_cur_str], 0
jz @f
mov [disasm_start_pos], eax
 
.ret:
ret
 
@@:
call update_disasm
 
.err:
mov esi, aInvAddr
jmp put_message
 
;-----------------------------------------------------------------------------
; Access to register value event
 
OnReg:
mov esi, [curarg]
call skip_spaces
call get_arg.skip_spaces
call find_reg
jnc @f
 
.err:
mov esi, RSyntax
jmp put_message
 
@@:
call skip_spaces
call get_arg.skip_spaces
test al, al
jz .err
cmp al, '='
jnz @f
inc esi
call skip_spaces
call get_arg.skip_spaces
test al, al
jz .err
 
@@:
push edi
call calc_expression
2428,22 → 1283,28
jb .16
mov [_eax+edi*4], eax
jmp .ret
 
.16:
mov word [_eax+(edi+8)*4], ax
jmp .ret
 
.8lo:
mov byte [_eax+(edi+4)*4], al
jmp .ret
 
.8hi:
mov byte [_eax+(edi+4)*4+1], al
jmp .ret
 
.eip:
mov [_eip], eax
call update_disasm_eip
 
.ret:
call set_context
jmp redraw_registers
jmp draw_registers.redraw
 
;-----------------------------------------------------------------------------
; Breakpoints manipulation
OnBp:
mov esi, [curarg]
2457,24 → 1318,30
jz .notfound
mov esi, aDuplicateBreakpoint
jmp .sayerr
 
.notfound:
mov bl, 1
call add_breakpoint
jnc .ret
mov esi, aBreakpointLimitExceeded
 
.sayerr:
call put_message
 
.ret:
jmp redraw_disasm
jmp draw_disasm.redraw
 
OnBpmb:
mov dh, 0011b
jmp DoBpm
 
OnBpmw:
mov dh, 0111b
jmp DoBpm
 
OnBpmd:
mov dh, 1111b
 
DoBpm:
mov esi, [curarg]
cmp byte [esi], 'w'
2481,6 → 1348,7
jnz @f
and dh, not 2
inc esi
 
@@:
push edx
call calc_expression
2487,8 → 1355,9
pop edx
jnc @f
ret
 
; ebp = expression, dh = flags
@@:
; ebp=expression, dh=flags
movzx eax, dh
shr eax, 2
test ebp, eax
2495,6 → 1364,7
jz @f
mov esi, aUnaligned
jmp put_message
 
@@:
mov eax, ebp
mov bl, 0Bh
2502,25 → 1372,28
jnc @f
mov esi, aBreakpointLimitExceeded
jmp put_message
 
; now find index
@@:
; now find index
push eax
xor ecx, ecx
 
.l1:
cmp [drx_break+ecx*4], 0
jnz .l2
push 69
pop eax
;push 69
;pop eax
push ecx
mov dl, cl
mov ecx, [debuggee_pid]
;mov ecx, [debuggee_pid]
mov esi, ebp
push 9
pop ebx
mcall
;push 9
;pop ebx
mcall 69, 9, [debuggee_pid]
test eax, eax
jz .ok
pop ecx
 
.l2:
inc ecx
cmp ecx, 4
2529,6 → 1402,7
call clear_breakpoint
mov esi, aBreakpointLimitExceeded
jmp put_message
 
.ok:
pop ecx
pop eax
2542,7 → 1416,9
 
OnBc:
mov esi, [curarg]
@@: call get_hex_number
 
@@:
call get_hex_number
jc OnBp.ret
call clear_breakpoint
jmp @b
2549,7 → 1425,9
 
OnBd:
mov esi, [curarg]
@@: call get_hex_number
 
@@:
call get_hex_number
jc OnBp.ret
call disable_breakpoint
jmp @b
2556,7 → 1434,9
 
OnBe:
mov esi, [curarg]
@@: call get_hex_number
 
@@:
call get_hex_number
jc OnBp.ret
push eax
call find_enabled_breakpoint
2564,14 → 1444,17
jz .err
call enable_breakpoint
jmp @b
 
.err:
mov esi, OnBeErrMsg
jmp put_message
 
; TODO: split it out in parser.inc
get_hex_number:
call skip_spaces
call get_arg.skip_spaces
xor ecx, ecx
xor edx, edx
 
@@:
lodsb
call is_hex_digit
2580,6 → 1463,7
or dl, al
inc ecx
jmp @b
 
.ret:
dec esi
cmp ecx, 1
2586,6 → 1470,9
xchg eax, edx
ret
 
;-----------------------------------------------------------------------------
; Breakpoints list event
 
OnBl:
mov esi, [curarg]
cmp byte [esi], 0
2601,14 → 1488,18
test byte [edi+4], 1
jz .err
call show_break_info
 
.ret:
ret
 
.err:
mov esi, aInvalidBreak
jmp put_message
 
.listall:
mov edi, breakpoints
xor eax, eax
 
@@:
test byte [edi+4], 1
jz .cont
2615,6 → 1506,7
push edi eax
call show_break_info
pop eax edi
 
.cont:
add edi, 6
inc eax
2622,6 → 1514,8
jb @b
ret
 
;-----------------------------------------------------------------------------
show_break_info:
push edi
test byte [edi+4], 8
2631,6 → 1525,7
mov esi, aBreakNum
call put_message_nodraw
jmp .cmn
 
.dr:
push eax
mov esi, aMemBreak1
2641,6 → 1536,7
test byte [edi+5], 2
jz @f
mov esi, aMemBreak3
 
@@:
call put_message_nodraw
pop edi
2652,6 → 1548,7
test byte [edi+5], 4
jnz @f
mov esi, aMemBreak4
 
@@:
call put_message_nodraw
pop edi
2659,6 → 1556,7
push dword [edi]
mov esi, aMemBreak7
call put_message_nodraw
 
.cmn:
pop edi
test byte [edi+4], 2
2667,20 → 1565,27
mov esi, aDisabled
call put_message_nodraw
pop edi
 
@@:
test byte [edi+4], 4
jz @f
mov esi, aOneShot
call put_message_nodraw
 
@@:
mov esi, newline
jmp put_message
 
;-----------------------------------------------------------------------------
; Add breakpoint
; in: EAX = address; BL = flags
; out: CF = 1 => error
; CF = 0 and EAX = breakpoint number
 
add_breakpoint:
; in: eax=address, bl=flags
; out: CF=1 => error, CF=0 => eax=breakpoint number
xor ecx, ecx
mov edi, breakpoints
 
@@:
test byte [edi+4], 1
jz .found
2690,6 → 1595,7
jb @b
stc
ret
 
.found:
stosd
xchg eax, ecx
2700,20 → 1606,27
push eax
call enable_breakpoint
pop eax
 
@@:
clc
ret
 
;-----------------------------------------------------------------------------
; Remove breakpoint
 
clear_breakpoint:
cmp eax, breakpoints_n
jae .ret
mov ecx, 4
inc eax
 
.1:
cmp [drx_break-4+ecx*4], eax
jnz @f
and [drx_break-4+ecx*4], 0
@@: loop .1
 
@@:
loop .1
dec eax
push eax
add eax, eax
2725,9 → 1638,13
call disable_breakpoint
pop edi
mov byte [edi], 0
 
.ret:
ret
 
;-----------------------------------------------------------------------------
; Disable breakpoint
 
disable_breakpoint:
cmp eax, breakpoints_n
jae .ret
2741,30 → 1658,35
test byte [edi-1], 8
jnz .dr
push esi
push 7
pop ebx
push 69
pop eax
mov ecx, [debuggee_pid]
xor edx, edx
inc edx
mov esi, [edi-5]
mcall
;push 7
;pop ebx
;push 69
;pop eax
;mov ecx, [debuggee_pid]
;xor edx, edx
;inc edx
;mov esi, [edi-5]
mcall 69, 7, [debuggee_pid], 1, [edi-5]
pop esi
 
.ret:
ret
 
.dr:
mov dl, [edi]
shr dl, 6
mov dh, 80h
push 69
pop eax
push 9
pop ebx
mov ecx, [debuggee_pid]
mcall
;push 69
;pop eax
;push 9
;pop ebx
;mov ecx, [debuggee_pid]
mcall 69, 9, [debuggee_pid]
ret
 
;-----------------------------------------------------------------------------
; Enable breakpoint
 
enable_breakpoint:
push esi
cmp eax, breakpoints_n
2778,26 → 1700,28
and byte [edi-1], not 2
test byte [edi-1], 8
jnz .dr
push 6
pop ebx
push 69
pop eax
mov esi, [edi-5]
mov ecx, [debuggee_pid]
xor edx, edx
inc edx
mcall
;push 6
;pop ebx
;push 69
;pop eax
;mov esi, [edi-5]
;mov ecx, [debuggee_pid]
;xor edx, edx
;inc edx
mcall 69, 6, [debuggee_pid], 1, [edi-5]
dec eax
jnz .err
mov al, 69
;mov al, 69
push 0xCC
mov edi, esp
inc ebx
mcall
mcall 69
pop eax
 
.ret:
pop esi
ret
 
.err:
or byte [edi-1], 2
mov esi, aBreakErr
2804,27 → 1728,32
call put_message
pop esi
ret
 
.dr:
push 9
pop ebx
push 69
pop eax
;push 9
;pop ebx
;push 69
;pop eax
mov esi, [edi-5]
mov ecx, [debuggee_pid]
;mov ecx, [debuggee_pid]
mov dl, [edi]
shr dl, 6
mov dh, [edi]
and dh, 0xF
mcall
mcall 69, 9, [debuggee_pid]
test eax, eax
jnz .err
pop esi
ret
 
;-----------------------------------------------------------------------------
; Find breakpoint
 
find_breakpoint:
xor ecx, ecx
xchg eax, ecx
mov edi, breakpoints
 
@@:
test byte [edi+4], 1
jz .cont
2832,6 → 1761,7
jnz .cont
cmp [edi], ecx
jz .found
 
.cont:
add edi, 6
inc eax
2838,13 → 1768,18
cmp eax, breakpoints_n
jb @b
or eax, -1
 
.found:
ret
 
;-----------------------------------------------------------------------------
;
 
find_enabled_breakpoint:
xor ecx, ecx
xchg eax, ecx
mov edi, breakpoints
 
@@:
test byte [edi+4], 1
jz .cont
2852,6 → 1787,7
jnz .cont
cmp [edi], ecx
jz .found
 
.cont:
add edi, 6
inc eax
2858,9 → 1794,15
cmp eax, breakpoints_n
jb @b
or eax, -1
 
.found:
ret
 
; TODO: add find_disabled_breakpoint
 
;-----------------------------------------------------------------------------
; Unpack executable event
 
OnUnpack:
; program must be loaded - checked when command was parsed
; program must be stopped
2869,6 → 1811,7
jz put_message
; all breakpoints must be disabled
mov edi, breakpoints
 
@@:
test byte [edi+4], 1
jz .cont
2876,6 → 1819,7
jnz .cont
mov esi, aEnabledBreakErr
jmp put_message
 
.cont:
add edi, 6
cmp edi, breakpoints+breakpoints_n*6
2888,22 → 1832,25
mov dx, 1111b*256
push 0xC
pop esi
 
@@:
push 69
pop eax
mcall
;push 69
;pop eax
mcall 69
test eax, eax
jz .breakok
inc edx
cmp dl, 4
jb @b
 
.breakok:
call GoOn
 
; now wait for event
.wait:
push 10
pop eax
mcall
;push 10
;pop eax
mcall 10
dec eax
jz .redraw
dec eax
2913,30 → 1860,35
; button; we have only one button, close
or eax, -1
mcall
 
.redraw:
call draw_window
jmp .wait
 
.key:
mov al, 2
mcall
cmp ah, 3 ; Ctrl+C
jnz .wait
 
.userbreak:
mov esi, aInterrupted
 
.x1:
push edx esi
call put_message
pop esi edx
or dh, 80h
push 69
pop eax
push 9
pop ebx
mov ecx, [debuggee_pid]
mcall
;push 69
;pop eax
;push 9
;pop ebx
;mov ecx, [debuggee_pid]
mcall 69, 9, [debuggee_pid]
cmp esi, aUnpacked
jnz OnSuspend
jmp AfterSuspend
 
.debug:
cmp [dbgbuflen], 4*3
jnz .notour
2944,6 → 1896,7
jnz .notour
test byte [dbgbuf+8], 1
jnz .our
 
.notour:
mov esi, aInterrupted
push edx
2950,27 → 1903,28
call put_message
pop edx
or dh, 80h
push 69
pop eax
push 9
pop ebx
mov ecx, [debuggee_pid]
mcall
;push 69
;pop eax
;push 9
;pop ebx
;mov ecx, [debuggee_pid]
mcall 69, 9, [debuggee_pid]
jmp debugmsg
 
.our:
and [dbgbuflen], 0
push edx
call get_context
push eax
mov al, 69
mov bl, 6
mov ecx, [debuggee_pid]
mov edi, esp
push 4
pop edx
push 0xC
pop esi
mcall
;mov al, 69
;mov bl, 6
;mov ecx, [debuggee_pid]
;mov edi, esp
;push 4
;pop edx
;push 0xC
;pop esi
mcall 69, 6, [debuggee_pid], 4, 0xC, esp
pop eax
pop edx
cmp eax, [_eip]
2977,18 → 1931,31
jz .done
call DoResume
jmp .wait
 
.done:
mov esi, aUnpacked
jmp .x1
 
;-----------------------------------------------------------------------------
; Working with program symbols
;
; TODO: split to symbols.inc
 
include 'sort.inc'
 
; compare what? Add context-relative comment and name
compare:
cmpsd
jnz @f
cmp esi, edi
@@: ret
 
@@:
ret
 
; purpose of this function?
compare2:
cmpsd
 
@@:
cmpsb
jnz @f
2995,6 → 1962,7
cmp byte [esi-1], 0
jnz @b
cmp esi, edi
 
@@:
ret
 
3004,8 → 1972,11
mcall 68, 13
and [symbols], 0
and [num_symbols], 0
 
@@:
ret
;-----------------------------------------------------------------------------
; Load symbols event
 
OnLoadSymbols.fileerr:
test ebp, ebp
3012,6 → 1983,7
jz @f
mcall 68, 13, edi
ret
 
@@:
push eax
mcall 68, 13, edi
3023,6 → 1995,7
mov esi, [load_err_msgs + eax*4]
test esi, esi
jnz put_message
 
.unk:
mov esi, unk_err_msg2
jmp put_message
3032,11 → 2005,15
; load input file
mov esi, [curarg]
call free_symbols
 
.silent:
xor edi, edi
cmp [num_symbols], edi
jz @f
ret
call free_symbols
;ret
@@:
mov ebx, fn70_attr_block
mov [ebx+21], esi
3061,6 → 2038,7
lea edx, [ecx+edi-1] ; edx = EOF-1
mov esi, edi
xor ecx, ecx
 
.calcloop:
cmp esi, edx
jae .calcdone
3068,6 → 2046,7
jnz .skipline
inc esi
inc esi
 
@@:
cmp esi, edx
jae .calcdone
3080,6 → 2059,7
cmp al, 15
jbe @b
dec esi
 
@@:
cmp esi, edx
ja .calcdone
3091,6 → 2071,7
jz @b
add ecx, 12+1
inc [num_symbols]
 
@@:
inc ecx
cmp esi, edx
3101,6 → 2082,7
cmp al, 0xA
jz .calcloop
jmp @b
 
.skipline:
cmp esi, edx
jae .calcdone
3110,6 → 2092,7
cmp al, 0xA
jz .calcloop
jmp .skipline
 
.calcdone:
mcall 68, 12
test eax, eax
3118,9 → 2101,11
mov ecx, edi
mov al, 68
mcall
 
.memerr:
mov esi, aNoMemory
jmp put_message
 
.memok:
mov [symbols], eax
mov ebx, eax
3129,7 → 2114,9
mov edi, [num_symbols]
lea ebp, [eax+edi*4]
lea edi, [eax+edi*8]
; parse input data, esi->input, edx->EOF, ebx->ptrs, edi->names
 
; parse input data,
; esi->input, edx->EOF, ebx->ptrs, edi->names
.readloop:
cmp esi, edx
jae .readdone
3139,6 → 2126,7
inc esi
xor eax, eax
xor ecx, ecx
 
@@:
shl ecx, 4
add ecx, eax
3153,6 → 2141,7
cmp al, 15
jbe @b
dec esi
 
@@:
cmp esi, edx
ja .readdone
3169,6 → 2158,7
mov dword [edi], ecx
add edi, 4
stosb
 
@@:
xor eax, eax
stosb
3181,6 → 2171,7
jz .readloop
mov byte [edi-1], al
jmp @b
 
.readline:
cmp esi, edx
jae .readdone
3190,6 → 2181,7
cmp al, 0xA
jz .readloop
jmp .readline
 
.readdone:
pop ecx
mcall 68, 13
3203,17 → 2195,22
call sort
mov esi, aSymbolsLoaded
call put_message
jmp redraw_disasm
jmp draw_disasm.redraw
 
;-----------------------------------------------------------------------------
;
; in: EAX = address
; out: ESI, CF
 
find_symbol:
; in: eax=address
; out: esi, CF
cmp [num_symbols], 0
jnz @f
 
.ret0:
xor esi, esi
stc
ret
 
@@:
push ebx ecx edx
xor edx, edx
3225,10 → 2222,13
jb @f
pop edx ecx ebx
jmp .ret0
 
@@:
; invariant: symbols_addr[edx] < eax < symbols_addr[ecx]
; TODO: add meaningful label names
.0:
push edx
 
.1:
add edx, ecx
sar edx, 1
3240,12 → 2240,15
ja .2
mov [esp], edx
jmp .1
 
.2:
mov ecx, edx
pop edx
jmp .0
 
.donecont:
dec edx
 
.done:
test edx, edx
jz @f
3252,8 → 2255,10
mov ebx, [esi+edx*4-4]
cmp [ebx], eax
jz .donecont
 
@@:
pop ecx
 
.donez:
mov esi, [esi+edx*4]
add esi, 4
3260,6 → 2265,7
pop edx ecx ebx
clc
ret
 
.done2:
lea esi, [esi+edx*4]
pop ecx edx ecx ebx
3266,15 → 2272,19
stc
ret
 
;-----------------------------------------------------------------------------
;
; in: esi->name
; out: if found: CF = 0, EAX = value
; otherwise CF = 1
find_symbol_name:
; in: esi->name
; out: if found: CF clear, eax=value
; otherwise CF set
cmp [num_symbols], 0
jnz @f
 
.stc_ret:
stc
ret
 
@@:
push ebx ecx edx edi
push -1
3282,9 → 2292,11
mov ebx, [symbols]
mov ecx, [num_symbols]
lea ebx, [ebx+ecx*4]
; invariant: symbols_name[edx] < name < symbols_name[ecx]
.0:
push edx
 
.1:
add edx, ecx
sar edx, 1
3295,12 → 2307,15
jb .2
mov [esp], edx
jmp .1
 
.2:
mov ecx, edx
pop edx
jmp .0
 
.done:
pop ecx
 
.donez:
mov eax, [ebx+edx*4]
mov eax, [eax]
3307,6 → 2322,7
pop edi edx ecx ebx
clc
ret
 
.done2:
pop edx edi edx ecx ebx
stc
3316,2373 → 2332,22
mov edi, [ebx+edx*4]
push esi
add edi, 4
 
@@:
cmpsb
jnz @f
cmp byte [esi-1], 0
jnz @b
@@:
pop esi
ret
 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; DISASSEMBLER ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
disasm_get_byte:
; out: al=byte
push ecx
mov ecx, [disasm_cur_pos]
sub ecx, [disasm_start_pos]
cmp ecx, [disasm_buf_size]
jae disasm_err
mov al, [disasm_buffer+ecx]
pop ecx
inc [disasm_cur_pos]
ret
disasm_get_word:
push ecx
mov ecx, [disasm_cur_pos]
sub ecx, [disasm_start_pos]
inc ecx
cmp ecx, [disasm_buf_size]
jae disasm_err
mov ax, word [disasm_buffer-1+ecx]
pop ecx
add [disasm_cur_pos], 2
ret
disasm_get_dword:
push ecx
mov ecx, [disasm_cur_pos]
sub ecx, [disasm_start_pos]
add ecx, 3
cmp ecx, [disasm_buf_size]
jae disasm_err
mov eax, dword [disasm_buffer-3+ecx]
pop ecx
add [disasm_cur_pos], 4
ret
 
disasm_err:
mov esp, ebp
stc_ret:
stc
ret
disasm_ret:
mov esp, ebp
and byte [edi], 0
ret
 
disasm_instr:
mov ebp, esp
cmp [debuggee_pid], 0
jz stc_ret
mov edi, disasm_string
xor ecx, ecx
; ecx=flags
disasm_loop1:
xor eax, eax
call disasm_get_byte
jmp dword [disasm_table_1 + eax*4]
 
cop0:
clock:
csegcs:
csegds:
cseges:
csegss:
csegfs:
cseggs:
mov esi, cmd1
iglobal
cmd1:
db 0x2E,3,'cs:'
db 0x36,3,'ss:'
db 0x3E,3,'ds:'
db 0x26,3,'es:'
db 0x64,3,'fs:'
db 0x65,3,'gs:'
db 0x06,10,'push es'
db 0x07,10,'pop es'
db 0x0E,10,'push cs'
db 0x16,10,'push ss'
db 0x17,10,'pop ss'
db 0x1E,10,'push ds'
db 0x1F,10,'pop ds'
db 0x27,3,'daa'
db 0x2F,3,'das'
db 0x37,3,'aaa'
db 0x3F,3,'aas'
db 0x60,6,0,'pusha'
db 0x61,5,0,'popa'
db 0x90,3,'nop'
db 0x9B,5,'fwait'
db 0x9C,6,0,'pushf'
db 0x9D,5,0,'popf'
db 0x9E,4,'sahf'
db 0x9F,4,'lahf'
db 0xA4,5,'movsb'
db 0xA5,5,0,'movs'
db 0xA6,5,'cmpsb'
db 0xA7,5,0,'cmps'
db 0xAA,5,'stosb'
db 0xAB,5,0,'stos'
db 0xAC,5,'lodsb'
db 0xAD,5,0,'lods'
db 0xAE,5,'scasb'
db 0xAF,5,0,'scas'
db 0xC3,3,'ret'
db 0xC9,5,'leave'
db 0xCC,4,'int3'
db 0xF0,4,'lock'
db 0xF5,3,'cmc'
db 0xF8,3,'clc'
db 0xF9,3,'stc'
db 0xFA,3,'cli'
db 0xFB,3,'sti'
db 0xFC,3,'cld'
db 0xFD,3,'std'
cmd2:
db 0x05,7,'syscall'
db 0x06,4,'clts'
db 0x31,5,'rdtsc'
db 0x34,8,'sysenter'
db 0xA2,5,'cpuid'
db 0x77,4,'emms'
endg
jmp @f
ccpuid:
crdtsc:
cemms:
cop0_F:
mov esi, cmd2
@@:
cmp al, [esi]
jz .found
inc esi
movzx edx, byte [esi]
inc esi
add esi, edx
jmp @b
.found:
inc esi
lodsb
cmp byte [esi], 0
jz @f
movzx ecx, al
disasm_1:
rep movsb
and byte [edi], 0
ret
@@:
mov dl, ch
movzx ecx, al
dec ecx
inc esi
rep movsb
test dl, 1
mov al, 'w'
jnz @f
mov al, 'd'
@@: stosb
and byte [edi], 0
ret
 
c67:
or ch, 2
jmp disasm_loop1
c66:
or ch, 1
jmp disasm_loop1
 
cxlat:
cunk:
cerr:
mov eax, '???'
stosd
clc
ret
 
cF:
call disasm_get_byte
jmp dword [disasm_table_2 + eax*4]
 
crep:
push [disasm_cur_pos]
call disasm_get_byte
cmp al, 0x0F
jz .sse
mov dl, al
mov eax, 'rep '
stosd
mov al, dl
@@:
and eax, not 1
cmp al, 0x66
jnz @f
call disasm_get_byte
mov dl, al
jmp @b
@@:
cmp al, 0xA6
jz .repz
cmp al, 0xAE
jz .repz
cmp al, 0xA4
jz .prefix
cmp al, 0xAA
jz .prefix
cmp al, 0xAC
jz .prefix
cmp al, 0x6C
jz .prefix
cmp al, 0x6E
jz .prefix
.noprefix:
pop [disasm_cur_pos]
and byte [edi-1], 0
ret
.repz:
mov byte [edi-1], 'z'
mov al, ' '
stosb
.prefix:
pop [disasm_cur_pos]
jmp disasm_loop1
.sse:
pop eax
call disasm_get_byte
iglobal
rep_sse_cmds:
db 0x58,3,'add'
db 0xC2,3,'cmp'
db 0,0
endg
mov esi, rep_sse_cmds+1
@@:
movzx edx, byte [esi]
cmp al, [esi-1]
jz @f
lea esi, [esi+edx+2]
cmp byte [esi], 0
jnz @b
sub [disasm_cur_pos], 2
mov eax, 'rep'
stosd
ret
@@:
push ecx
mov ecx, edx
inc esi
rep movsb
pop ecx
mov al, 's'
stosb
jmp rep_sse_final
 
crepnz:
call disasm_get_byte
cmp al, 0x0F
jz .sse
mov dl, al
mov eax, 'repn'
stosd
mov al, 'z'
stosb
mov al, ' '
stosb
movzx eax, dl
cmp al, 0x6C
jb crep.noprefix
cmp al, 0x6F
jbe .prefix
cmp al, 0xA4
jb crep.noprefix
cmp al, 0xA7
jbe .prefix
cmp al, 0xAA
jb crep.noprefix
cmp al, 0xAF
ja crep.noprefix
.prefix:
jmp cop0
.sse:
call disasm_get_byte
mov esi, rep_sse_cmds+1
@@:
movzx edx, byte [esi]
cmp al, [esi-1]
jz .found0
lea esi, [esi+edx+2]
cmp byte [esi], 0
jnz @b
mov esi, sse_cmds2+1
@@:
movzx edx, byte [esi]
cmp al, [esi-1]
jz .found1
lea esi, [esi+edx+2]
cmp byte [esi], 0
jnz @b
sub [disasm_cur_pos], 2
mov eax, 'repn'
stosd
mov al, 'z'
stosb
and byte [edi], 0
ret
.found0:
push ecx
mov ecx, edx
inc esi
rep movsb
pop ecx
mov al, 's'
stosb
mov al, 'd'
jmp rep_sse_final
.found1:
push ecx
mov ecx, edx
inc esi
rep movsb
pop ecx
mov al, 'p'
stosb
mov al, 's'
rep_sse_final:
stosb
push ecx
push 5
pop ecx
sub ecx, edx
adc ecx, 1
mov al, ' '
rep stosb
pop ecx
or ch, 1
jmp disasm_mmx1
 
macro disasm_set_modew
{
test al, 1
jz @f
or ch, 80h
@@:
}
 
cmov2:
disasm_set_modew
; mov r/m,i
call disasm_get_byte
dec [disasm_cur_pos]
test al, 00111000b
jnz cunk
mov eax, 'mov '
stosd
mov eax, ' '
stosd
call disasm_readrmop
mov ax, ', '
stosw
xor eax, eax
test ch, 80h
jnz .1
call disasm_get_byte
jmp .3
.1:
test ch, 1
jnz .2
call disasm_get_dword
jmp .3
.2:
call disasm_get_word
.3:
call disasm_write_num
and byte [edi], 0
ret
 
cret2:
mov eax, 'ret '
stosd
mov eax, ' '
stosd
xor eax, eax
jmp cmov2.2
 
disasm_write_num:
push esi
cmp eax, 0x80
jl .nosymb
lea esi, [eax-1]
test eax, esi
jz .nosymb
call find_symbol
jc .nosymb
@@:
lodsb
test al, al
jz @f
stosb
jmp @b
@@:
pop esi
ret
.nosymb:
pop esi
push ecx eax
inc edi
@@:
mov ecx, eax
shr eax, 4
jz @f
inc edi
jmp @b
@@:
pop eax
cmp ecx, 10
jb @f
inc edi
@@:
push edi eax
@@:
mov ecx, eax
and al, 0xF
cmp al, 10
sbb al, 69h
das
dec edi
mov [edi], al
mov eax, ecx
shr eax, 4
jnz @b
cmp ecx, 10
jb @f
mov byte [edi-1], '0'
@@:
pop eax edi ecx
cmp eax, 10
jb @f
mov byte [edi], 'h'
inc edi
@@:
ret
 
iglobal
label disasm_regs32 dword
label disasm_regs dword
db 'eax',0
db 'ecx',0
db 'edx',0
db 'ebx',0
db 'esp',0
db 'ebp',0
db 'esi',0
db 'edi',0
disasm_regs16 dw 'ax','cx','dx','bx','sp','bp','si','di'
disasm_regs8 dw 'al','cl','dl','bl','ah','ch','dh','bh'
disasm_scale db '1248'
endg
disasm_readrmop:
call disasm_get_byte
test ch, 40h
jnz .skip_size
push eax
and al, 0xC0
cmp al, 0xC0
pop eax
jz .skip_size
test ch, 80h
jz .byte
test ch, 1
jnz .word
mov dword [edi], 'dwor'
mov byte [edi+4], 'd'
inc edi
jmp @f
.byte:
test ch, 20h
jz .qb
mov byte [edi], 't'
inc edi
.qb:
mov dword [edi], 'byte'
jmp @f
.word:
test ch, 20h
jz .qw
mov byte [edi], 'q'
inc edi
.qw:
mov dword [edi], 'word'
@@:
mov byte [edi+4], ' '
add edi, 5
.skip_size:
test ch, 2
jnz disasm_readrmop16
push ecx
movzx ecx, al
and eax, 7
shr ecx, 6
jz .vmod0
jp .vmod3
mov byte [edi], '['
inc edi
cmp al, 4
jz .sib1
mov eax, [disasm_regs+eax*4]
stosd
dec edi
jmp @f
.sib1:
call .parse_sib
@@:
mov al, '+'
stosb
dec ecx
jz .vmod1
call disasm_get_dword
jmp @f
.vmod1:
call disasm_get_byte
movsx eax, al
@@:
test eax, eax
jns .2
neg eax
mov byte [edi-1], '-'
.2:
call disasm_write_num
.2a:
mov al, ']'
stosb
pop ecx
ret
.vmod3:
pop ecx
test ch, 10h
jnz .vmod3_mmi
test ch, 80h
jz .vmod3_byte
test ch, 1
jnz .vmod3_word
test ch, 20h
jnz .vmod3_sti
mov eax, [disasm_regs32+eax*4]
stosd
dec edi
ret
.vmod3_byte:
mov ax, [disasm_regs8+eax*2]
@@:
stosw
ret
.vmod3_word:
mov ax, [disasm_regs16+eax*2]
jmp @b
.vmod3_sti:
mov word [edi], 'st'
add al, '0'
mov byte [edi+2], al
add edi, 3
ret
.vmod3_mmi:
disasm_write_mmreg = $
test ch, 1
jz @f
mov byte [edi], 'x'
inc edi
@@:
mov word [edi], 'mm'
add al, '0'
mov byte [edi+2], al
add edi, 3
ret
.vmod0:
mov byte [edi], '['
inc edi
cmp al, 4
jz .sib2
cmp al, 5
jz .ofs32
mov eax, [disasm_regs+eax*4]
stosd
mov byte [edi-1], ']'
pop ecx
ret
.ofs32:
call disasm_get_dword
jmp .2
.sib2:
call .parse_sib
mov al, ']'
stosb
pop ecx
ret
.parse_sib:
call disasm_get_byte
push edx
mov dl, al
mov dh, 0
and eax, 7
cmp al, 5
jnz @f
jecxz .sib0
@@:
mov eax, [disasm_regs+eax*4]
stosd
dec edi
mov dh, 1
.sib0:
mov al, dl
shr eax, 3
and eax, 7
cmp al, 4
jz .sibret
test dh, dh
jz @f
mov byte [edi], '+'
inc edi
@@:
mov eax, [disasm_regs+eax*4]
stosd
dec edi
shr dl, 6
jz @f
mov al, '*'
stosb
movzx eax, dl
mov al, [disasm_scale+eax]
stosb
@@:
.sibret:
test dh, dh
jnz .sibret2
call disasm_get_dword
cmp byte [edi-1], '['
jz @f
mov byte [edi], '+'
test eax, eax
jns .sibns
neg eax
mov byte [edi], '-'
.sibns:
inc edi
@@:
call disasm_write_num
.sibret2:
pop edx
ret
;-----------------------------------------------------------------------------
; Include disassembler engine
 
iglobal
disasm_rm16_1 dd 'bxsi','bxdi','bpsi','bpdi'
disasm_rm16_2 dw 'si','di','bp','bx'
endg
disasm_readrmop16:
push ecx
movzx ecx, al
and eax, 7
shr ecx, 6
jz .vmod0
jp disasm_readrmop.vmod3 ; mod=3 is the same in 16- and 32-bit code
; 1 or 2
mov byte [edi], '['
inc edi
cmp al, 4
jae @f
mov eax, [disasm_rm16_1+eax*4]
stosw
mov al, '+'
stosb
shr eax, 16
jmp .1
@@:
mov eax, dword [disasm_rm16_2+eax*2-4*2]
.1:
stosw
mov al, '+'
stosb
xor eax, eax
dec ecx
jnz .2
call disasm_get_byte
cbw
jmp @f
.2:
call disasm_get_word
@@:
test ax, ax
jns @f
mov byte [edi-1], '-'
neg ax
@@:
call disasm_write_num
.done1:
mov al, ']'
stosb
pop ecx
ret
.vmod0:
mov byte [edi], '['
inc edi
cmp al, 6
jz .ofs16
cmp al, 4
jae @f
mov eax, [disasm_rm16_1+eax*4]
stosw
mov al, '+'
stosb
shr eax, 16
jmp .3
@@:
mov eax, dword [disasm_rm16_2+eax*2-4*2]
.3:
stosw
jmp .done1
.ofs16:
xor eax, eax
call disasm_get_word
call disasm_write_num
jmp .done1
include 'disasm.inc'
 
cpush21:
mov eax, 'push'
stosd
mov eax, ' '
stosd
disasm_i32:
call disasm_get_dword
call disasm_write_num
and byte [edi], 0
ret
 
cpush22:
mov eax, 'push'
stosd
mov eax, ' '
stosd
call disasm_get_byte
movsx eax, al
@@:
call disasm_write_num
and byte [edi], 0
ret
 
center:
mov eax, 'ente'
stosd
mov eax, 'r '
stosd
xor eax, eax
call disasm_get_word
call disasm_write_num
mov al, ','
stosb
mov al, ' '
stosb
xor eax, eax
call disasm_get_byte
jmp @b
 
cinc1:
; inc reg32
cdec1:
; dec reg32
cpush1:
; push reg32
cpop1:
; pop reg32
cbswap:
; bswap reg32
mov edx, eax
and edx, 7
shr eax, 3
sub al, 8
mov esi, 'inc '
jz @f
mov esi, 'dec '
dec al
jz @f
mov esi, 'push'
dec al
jz @f
mov esi, 'pop '
dec al
jz @f
mov esi, 'bswa'
@@:
xchg eax, esi
stosd
mov eax, ' '
jz @f
mov al, 'p'
@@:
stosd
xchg eax, edx
call disasm_write_reg1632
and byte [edi], 0
ret
 
cxchg1:
; xchg eax,reg32
and eax, 7
xchg eax, edx
mov eax, 'xchg'
stosd
mov eax, ' '
stosd
xor eax, eax
call disasm_write_reg1632
mov ax, ', '
stosw
xchg eax, edx
call disasm_write_reg1632
and byte [edi], 0
ret
 
cint:
mov eax, 'int '
stosd
mov eax, ' '
stosd
disasm_i8u:
xor eax, eax
call disasm_get_byte
call disasm_write_num
and byte [edi], 0
ret
 
cmov11:
; mov r8,i8
mov ecx, eax
mov eax, 'mov '
stosd
mov eax, ' '
stosd
and ecx, 7
mov ax, [disasm_regs8+ecx*2]
stosw
mov ax, ', '
stosw
jmp disasm_i8u
 
cmov12:
; mov r32,i32
xchg eax, edx
mov eax, 'mov '
stosd
mov eax, ' '
stosd
xchg eax, edx
and eax, 7
call disasm_write_reg1632
mov ax, ', '
stosw
jmp cmov2.1
 
iglobal
disasm_shifts dd 'rol ','ror ','rcl ','rcr ','shl ','shr ','sal ','sar '
endg
cshift2:
; shift r/m,1 = D0/D1
cshift3:
; shift r/m,cl = D2/D3
disasm_set_modew
mov dl, al
call disasm_get_byte
dec [disasm_cur_pos]
shr al, 3
and eax, 7
mov eax, [disasm_shifts+eax*4]
stosd
mov eax, ' '
stosd
call disasm_readrmop
cmp dl, 0xD2
jb .s1
mov eax, ', cl'
stosd
and byte [edi], 0
ret
.s1:
mov eax, ', 1'
stosd
clc
ret
 
cshift1:
; shift r/m,i8 = C0/C1
disasm_set_modew
call disasm_get_byte
dec [disasm_cur_pos]
shr al, 3
and eax, 7
mov eax, [disasm_shifts+eax*4]
stosd
mov eax, ' '
stosd
call disasm_readrmop
mov ax, ', '
stosw
jmp disasm_i8u
 
caam:
mov eax, 'aam '
jmp @f
caad:
mov eax, 'aad '
@@:
stosd
mov eax, ' '
stosd
xor eax, eax
call disasm_get_byte
cmp al, 10
jz @f
call disasm_write_num
@@:
and byte [edi], 0
ret
 
cmov3:
; A0: mov al,[ofs32]
; A1: mov ax/eax,[ofs32]
; A2: mov [ofs32],al
; A3: mov [ofs32],ax/eax
mov edx, 'mov '
xchg eax, edx
stosd
mov eax, ' '
stosd
test dl, 2
jnz .1
call .write_acc
mov ax, ', '
stosw
call .write_ofs32
jmp .2
.1:
call .write_ofs32
mov ax, ', '
stosw
call .write_acc
.2: and byte [edi], 0
ret
.write_acc:
test dl, 1
jz .8bit
test ch, 1
jnz .16bit
mov eax, 'eax'
stosd
dec edi
ret
.16bit:
mov ax, 'ax'
stosw
ret
.8bit:
mov ax, 'al'
stosw
ret
.write_ofs32:
mov al, '['
stosb
call disasm_get_dword
call disasm_write_num
mov al, ']'
stosb
ret
 
disasm_write_reg:
test ch, 80h
jnz disasm_write_reg1632
mov ax, [disasm_regs8+eax*2]
stosw
ret
disasm_write_reg1632:
test ch, 1
jnz @f
mov eax, [disasm_regs32+eax*4]
stosd
dec edi
ret
@@:
mov ax, [disasm_regs16+eax*2]
stosw
ret
 
cmovzx: ; 0F B6/B7
cmovsx: ; 0F BE/BF
mov edx, eax
disasm_set_modew
mov eax, 'movz'
cmp dl, 0xB8
jb @f
mov eax, 'movs'
@@:
stosd
mov eax, 'x '
stosd
call disasm_get_byte
dec [disasm_cur_pos]
shr al, 3
and eax, 7
call disasm_write_reg1632
mov ax, ', '
stosw
or ch, 1 ; 2nd operand - 8 or 16 bits
call disasm_readrmop
and byte [edi], 0
ret
 
iglobal
disasm_op2cmds dd 'add ','or ','adc ','sbb ','and ','sub ','xor ','cmp '
endg
cop21:
disasm_set_modew
mov esi, 'test'
cmp al, 0A8h
jae @f
shr al, 3
and eax, 7
mov esi, [disasm_op2cmds+eax*4]
@@:
xchg eax, esi
stosd
mov eax, ' '
stosd
test ch, 80h
jnz .1632
mov eax, 'al, '
stosd
jmp disasm_i8u
.1632:
test ch, 1
jnz .16
mov eax, 'eax,'
stosd
mov al, ' '
stosb
call disasm_get_dword
jmp .x
.16:
mov eax, 'ax, '
stosd
xor eax, eax
call disasm_get_word
.x:
call disasm_write_num
and byte [edi], 0
ret
 
carpl:
xor edx, edx
or ch, 0C1h
mov eax, 'arpl'
jmp cop22.d2
 
ccmpxchg:
xor edx, edx
disasm_set_modew
or ch, 40h
mov eax, 'cmpx'
stosd
mov eax, 'chg '
jmp cop22.d1
 
cbsf:
cbsr:
or ch, 80h
 
cop22:
disasm_set_modew
or ch, 40h
mov edx, eax
mov esi, 'lea '
cmp al, 8Dh
jz @f
mov esi, 'imul'
cmp al, 0xAF
jz @f
mov esi, 'bsf '
cmp al, 0BCh
jz @f
mov esi, 'bsr '
cmp al, 0BDh
jz @f
mov esi, 'mov '
cmp al, 88h
jae @f
mov esi, 'xchg'
cmp al, 86h
jae @f
mov esi, 'test'
cmp al, 84h
jae @f
shr al, 3
and eax, 7
mov esi, [disasm_op2cmds+eax*4]
@@:
xchg eax, esi
.d2:
stosd
mov eax, ' '
.d1:
stosd
call disasm_get_byte
dec [disasm_cur_pos]
shr al, 3
and eax, 7
cmp dl, 0x8D
jz @f
cmp dl, 0x86
jz @f
cmp dl, 0x87
jz @f
cmp dl, 0xBC
jz @f
cmp dl, 0xBD
jz @f
test dl, 2
jz .d0
@@:
call disasm_write_reg
mov ax, ', '
stosw
call disasm_readrmop
and byte [edi], 0
ret
.d0:
push eax
call disasm_readrmop
mov ax, ', '
stosw
pop eax
call disasm_write_reg
and byte [edi], 0
ret
 
cbound:
mov edx, eax
mov eax, 'boun'
stosd
mov eax, 'd '
or ch, 0xC0
jmp cop22.d1
 
cop23:
disasm_set_modew
xchg eax, edx
call disasm_get_byte
dec [disasm_cur_pos]
shr eax, 3
and eax, 7
mov eax, [disasm_op2cmds+eax*4]
ctest:
stosd
mov eax, ' '
stosd
call disasm_readrmop
mov ax, ', '
stosw
test ch, 80h
jz .i8
cmp dl, 83h
jz .i8
test ch, 1
jnz .i16
call disasm_get_dword
jmp .ic
.i8:
xor eax, eax
call disasm_get_byte
cmp dl, 83h
jnz .ic
movsx eax, al
jmp .ic
.i16:
xor eax, eax
call disasm_get_word
.ic:
call disasm_write_num
and byte [edi], 0
ret
 
cmovcc:
or ch, 0C0h
and eax, 0xF
mov ax, [disasm_jcc_codes + eax*2]
mov dword [edi], 'cmov'
add edi, 4
stosw
mov ax, ' '
stosw
call disasm_get_byte
dec [disasm_cur_pos]
shr eax, 3
and eax, 7
call disasm_write_reg1632
mov ax, ', '
stosw
call disasm_readrmop
and byte [edi], 0
ret
 
cbtx1:
; btx r/m,i8 = 0F BA
or ch, 80h
call disasm_get_byte
dec [disasm_cur_pos]
shr al, 3
and eax, 7
cmp al, 4
jb cunk
mov eax, [btx1codes+eax*4-4*4]
stosd
mov eax, ' '
stosd
call disasm_readrmop
mov ax, ', '
stosw
jmp disasm_i8u
iglobal
btx1codes dd 'bt ','bts ','btr ','btc '
endg
cbtx2:
; btx r/m,r = 0F 101xx011 (A3,AB,B3,BB)
shr al, 3
and eax, 3
mov eax, [btx1codes+eax*4]
stosd
mov eax, ' '
stosd
or ch, 0xC0
call disasm_get_byte
dec [disasm_cur_pos]
shr al, 3
and eax, 7
push eax
call disasm_readrmop
mov ax, ', '
stosw
pop eax
call disasm_write_reg1632
and byte [edi], 0
ret
 
csetcc:
and eax, 0xF
mov ax, [disasm_jcc_codes + eax*2]
mov dword [edi], 'setc'
add edi, 3
stosw
mov ax, ' '
stosw
stosb
call disasm_readrmop
and byte [edi], 0
ret
 
iglobal
disasm_jcc_codes dw 'o ','no','b ','ae','z ','nz','be','a ','s ','ns','p ','np','l ','ge','le','g '
endg
cjcc1:
cjmp2:
cmp al, 0xEB
jz .1
and eax, 0xF
mov ax, [disasm_jcc_codes + eax*2]
jmp .2
.1:
mov ax, 'mp'
.2:
mov byte [edi], 'j'
inc edi
stosw
mov eax, ' '
stosb
stosd
call disasm_get_byte
movsx eax, al
disasm_rva:
add eax, [disasm_cur_pos]
call disasm_write_num
and byte [edi], 0
ret
 
ccall1:
cjmp1:
cjcc2:
mov edx, 'call'
cmp al, 0xE8
jz @f
mov edx, 'jmp '
cmp al, 0xE9
jz @f
mov edx, ' '
and eax, 0xF
mov dx, [disasm_jcc_codes+eax*2]
shl edx, 8
mov dl, 'j'
@@:
xchg eax, edx
stosd
mov eax, ' '
stosd
test ch, 1
jnz @f
call disasm_get_dword
jmp disasm_rva
@@:
call disasm_get_word
add eax, [disasm_cur_pos]
and eax, 0xFFFF
call disasm_write_num
and byte [edi], 0
ret
 
ccallf:
mov eax, 'call'
stosd
mov eax, ' '
stosd
mov al, 'd'
test ch, 1
jnz @f
mov al, 'p'
@@:
stosb
mov eax, 'word'
stosd
mov al, ' '
stosb
test ch, 1
jnz .1
call disasm_get_dword
jmp .2
.1:
xor eax, eax
call disasm_get_word
.2:
push eax
xor eax, eax
call disasm_get_word
call disasm_write_num
mov al, ':'
stosb
pop eax
call disasm_write_num
and byte [edi], 0
ret
 
iglobal
op11codes dd 'test',0,'not ','neg ','mul ','imul','div ','idiv'
op12codes dd 'inc ','dec ','call',0,'jmp ',0,'push',0
endg
cop1:
disasm_set_modew
xchg eax, edx
call disasm_get_byte
movzx esi, al
dec [disasm_cur_pos]
shr al, 3
and eax, 7
cmp dl, 0xFE
jnz @f
cmp al, 1
jbe @f
.0:
inc [disasm_cur_pos]
jmp cunk
@@:
and edx, 8
add eax, edx
cmp al, 11
jz .callfar
cmp al, 13
jz .jmpfar
mov eax, [op11codes+eax*4]
test eax, eax
jz .0
cmp eax, 'test'
jz ctest
.2:
stosd
mov eax, ' '
stosd
call disasm_readrmop
and byte [edi], 0
ret
.callfar:
mov eax, 'call'
.1:
cmp esi, 0xC0
jae .0
stosd
mov eax, ' '
stosd
mov eax, 'far '
stosd
mov al, 'd'
test ch, 1
jnz @f
mov al, 'p'
@@:
stosb
or ch, 1
call disasm_readrmop
and byte [edi], 0
ret
.jmpfar:
mov eax, 'jmp '
jmp .1
 
cpop2:
or ch, 80h
call disasm_get_byte
dec [disasm_cur_pos]
test al, 00111000b
jnz cunk
mov eax, 'pop '
jmp cop1.2
 
cloopnz:
mov eax, 'loop'
stosd
mov eax, 'nz '
test ch, 2
jz @f
mov ah, 'w'
@@: jmp cloop.cmn
cloopz:
mov eax, 'loop'
stosd
mov eax, 'z '
test ch, 2
jz @f
mov eax, 'zw '
@@: jmp cloop.cmn
 
cjcxz:
cloop:
cmp al, 0xE2
jz .loop
test ch, 2
jnz .jcxz
mov eax, 'jecx'
stosd
mov eax, 'z '
jmp .cmn
.jcxz:
mov eax, 'jcxz'
stosd
mov eax, ' '
jmp .cmn
.loop:
mov eax, 'loop'
stosd
mov eax, ' '
test ch, 2
jz .cmn
mov al, 'w'
.cmn:
stosd
call disasm_get_byte
movsx eax, al
add eax, [disasm_cur_pos]
test ch, 1
jz @f
and eax, 0xFFFF
@@:
disasm_write_num_done:
call disasm_write_num
and byte [edi], 0
ret
 
cimul1:
; imul r,r/m,i
or ch, 80h ; 32bit operation
xchg eax, edx
mov eax, 'imul'
stosd
mov eax, ' '
stosd
call disasm_get_byte
dec [disasm_cur_pos]
shr al, 3
and eax, 7
call disasm_write_reg1632
mov ax, ', '
stosw
call disasm_readrmop
mov ax, ', '
stosw
test ch, 1
jnz .16
cmp dl, 0x69
jz .op32
call disasm_get_byte
movsx eax, al
jmp disasm_write_num_done
.op32:
call disasm_get_dword
jmp disasm_write_num_done
.16:
cmp dl, 0x69
jz .op16
call disasm_get_byte
cbw
jmp disasm_write_num_done
.op16:
xor eax, eax
call disasm_get_word
jmp disasm_write_num_done
 
cshld:
cshrd:
mov edx, 'shld'
test al, 8
jz @f
mov edx, 'shrd'
@@:
xchg eax, edx
stosd
mov eax, ' '
stosd
call disasm_get_byte
dec [disasm_cur_pos]
shr al, 3
and eax, 7
push eax
or ch, 80h
call disasm_readrmop
mov ax, ', '
stosw
pop eax
call disasm_write_reg1632
mov ax, ', '
stosw
test dl, 1
jz disasm_i8u
mov ax, 'cl'
stosw
and byte [edi], 0
ret
 
ccbw:
mov eax, 'cbw '
test ch, 1
jnz @f
mov eax, 'cwde'
@@: stosd
and byte [edi], 0
ret
ccwd:
mov eax, 'cwd '
test ch, 1
jnz @b
mov eax, 'cdq '
jmp @b
 
ccmpxchg8b:
call disasm_get_byte
cmp al, 0xC0
jae cerr
shr al, 3
and al, 7
cmp al, 1
jnz cerr
dec [disasm_cur_pos]
mov eax, 'cmpx'
stosd
mov eax, 'chg8'
stosd
mov al, 'b'
stosb
mov al, ' '
stosb
or ch, 40h
call disasm_readrmop
and byte [edi], 0
ret
 
iglobal
fpuD8 dd 'add ','mul ','com ','comp','sub ','subr','div ','divr'
endg
 
cD8:
call disasm_get_byte
dec [disasm_cur_pos]
push eax
shr al, 3
and eax, 7
mov byte [edi], 'f'
inc edi
xchg eax, edx
mov eax, [fpuD8+edx*4]
stosd
mov ax, ' '
stosw
stosb
pop eax
cmp dl, 2
jb .1
cmp dl, 3
jbe .2
.1:
cmp al, 0xC0
jb .2
mov eax, 'st0,'
stosd
mov al, ' '
stosb
.2:
or ch, 80h or 20h
and ch, not 1
call disasm_readrmop
and byte [edi], 0
ret
 
iglobal
fpuD9_2:
dq 'fchs ','fabs ',0,0,'ftst ','fxam ',0,0
db 'fld1 fldl2t fldl2e fldpi fldlg2 fldln2 fldz '
dq 0
db 'f2xm1 fyl2x fptan fpatan fxtract fprem1 fdecstp fincstp '
db 'fprem fyl2xp1 fsqrt fsincos frndint fscale fsin fcos '
fpuD9_fnop db 'fnop '
endg
cD9:
call disasm_get_byte
sub al, 0xC0
jae .l1
dec [disasm_cur_pos]
shr al, 3
and eax, 7
cmp al, 7
jnz @f
mov eax, 'fnst'
stosd
mov eax, 'cw '
jmp .x1
@@:
cmp al, 5
jnz @f
mov eax, 'fldc'
stosd
mov eax, 'w '
.x1:
stosd
or ch, 0C1h
jmp .cmn
@@:
mov edx, 'fld '
test al, al
jz @f
mov edx, 'fst '
cmp al, 2
jz @f
mov edx, 'fstp'
cmp al, 3
jnz cunk
@@:
xchg eax, edx
stosd
mov eax, ' '
stosd
or ch, 80h
and ch, not 1
.cmn:
call disasm_readrmop
and byte [edi], 0
ret
.l1:
cmp al, 10h
jae .l2
mov edx, 'fld '
cmp al, 8
jb @f
mov edx, 'fxch'
@@:
xchg eax, edx
stosd
mov eax, ' '
stosd
xchg eax, edx
and al, 7
add al, '0'
shl eax, 16
mov ax, 'st'
stosd
clc
ret
.l2:
cmp al, 0x10
jnz @f
mov esi, fpuD9_fnop
jmp .l3
@@:
sub al, 0x20
jb cerr
lea esi, [fpuD9_2+eax*8]
cmp byte [esi], 0
jz cerr
.l3:
movsd
movsd
and byte [edi-1], 0
ret
 
cDA:
call disasm_get_byte
cmp al, 0xC0
jae cunk
dec [disasm_cur_pos]
shr al, 3
and eax, 7
mov word [edi], 'fi'
inc edi
inc edi
mov eax, [fpuD8+eax*4]
stosd
mov ax, ' '
stosw
or ch, 80h
and ch, not 1 ; 32-bit operand
call disasm_readrmop
and byte [edi], 0
ret
 
iglobal
fpuDB dd 'ild ',0,'ist ','istp',0,'ld ',0,'stp '
endg
cDB:
call disasm_get_byte
cmp al, 0xC0
jae .1
dec [disasm_cur_pos]
shr al, 3
and eax, 7
xchg eax, edx
mov eax, [fpuDB+edx*4]
test eax, eax
jz cerr
mov byte [edi], 'f'
inc edi
stosd
mov ax, ' '
stosw
stosb
or ch, 80h
and ch, not 1 ; 32-bit operand
cmp dl, 4
jb @f
or ch, 20h
and ch, not 80h ; 80-bit operand
@@:
call disasm_readrmop
and byte [edi], 0
ret
.1:
cmp al, 0xE3
jnz cunk
mov eax, 'fnin'
stosd
mov eax, 'it'
stosd
dec edi
ret ; CF cleared
 
iglobal
fpuDC dd 'add ','mul ',0,0,'subr','sub ','divr','div '
endg
cDC:
call disasm_get_byte
cmp al, 0xC0
jae .1
dec [disasm_cur_pos]
shr al, 3
and eax, 7
mov byte [edi], 'f'
inc edi
mov eax, [fpuD8+eax*4]
stosd
mov ax, ' '
stosw
stosb
or ch, 0A1h ; qword
call disasm_readrmop
and byte [edi], 0
ret
.1:
mov dl, al
shr al, 3
and eax, 7
mov eax, [fpuDC+eax*4]
test eax, eax
jz cerr
mov byte [edi], 'f'
inc edi
stosd
mov eax, ' s'
stosd
mov al, 't'
stosb
and edx, 7
lea eax, [edx+'0']
stosb
mov eax, ', st'
stosd
mov ax, '0'
stosw
ret ; CF cleared
 
iglobal
fpuDD dd 'fld ',0,'fst ','fstp',0,0,0,0
fpuDD_2 dq 'ffree ',0,'fst ','fstp ','fucom ','fucomp ',0,0
endg
cDD:
call disasm_get_byte
cmp al, 0xC0
jae .1
dec [disasm_cur_pos]
shr al, 3
and eax, 7
xchg eax, edx
mov eax, [fpuDD+edx*4]
test eax, eax
jz cunk
stosd
mov eax, ' '
stosd
or ch, 0A1h ; qword operand
call disasm_readrmop
and byte [edi], 0
ret
.1:
push eax
shr al, 3
and eax, 7
xchg eax, edx
mov eax, dword [fpuDD_2+edx*8]
test eax, eax
jz cerr
stosd
mov eax, dword [fpuDD_2+4+edx*8]
stosd
mov ax, 'st'
stosw
pop eax
and al, 7
add al, '0'
stosb
and byte [edi], 0
ret
 
iglobal
fpuDE dd 'add ','mul ',0,0,'subr','sub ','divr','div '
endg
cDE:
call disasm_get_byte
cmp al, 0xC0
jae .1
dec [disasm_cur_pos]
mov word [edi], 'fi'
inc edi
inc edi
shr al, 3
and eax, 7
mov eax, [fpuD8+eax*4]
stosd
mov ax, ' '
stosw
or ch, 81h ; force 16-bit
call disasm_readrmop
and byte [edi], 0
ret
.1:
push eax
shr al, 3
and eax, 7
xchg eax, edx
mov eax, [fpuDE+edx*4]
test eax, eax
jz .fcompp
mov byte [edi], 'f'
inc edi
stosd
mov al, 'p'
cmp byte [edi-1], ' '
jnz @f
mov byte [edi-1], al
mov al, ' '
@@: stosb
mov eax, ' st'
stosd
pop eax
and al, 7
add al, '0'
stosb
mov ax, ', '
stosw
mov eax, 'st0'
stosd
ret ; CF cleared
.fcompp:
pop eax
cmp al, 0xD9
jnz cerr
mov eax, 'fcom'
stosd
mov ax, 'pp'
stosw
and byte [edi], 0
ret
 
iglobal
fpuDF dd 'ild ',0,'ist ','istp','bld ','ild ','bstp','istp'
endg
 
cDF:
call disasm_get_byte
cmp al, 0xC0
jae .1
dec [disasm_cur_pos]
shr al, 3
and eax, 7
xchg eax, edx
mov eax, [fpuDF+edx*4]
test eax, eax
jz cerr
mov byte [edi], 'f'
inc edi
stosd
mov ax, ' '
stosw
stosb
or ch, 81h ; force 16-bit operand
cmp dl, 4
jb @f
or ch, 20h
test dl, 1
jnz @f
or ch, 40h
@@:
call disasm_readrmop
and byte [edi], 0
ret
.1:
cmp al, 0xE0
jnz cunk
mov eax, 'fnst'
stosd
mov eax, 'sw '
stosd
mov ax, 'ax'
stosw
and byte [edi], 0
ret
 
cmovd1:
mov eax, 'movd'
stosd
mov eax, ' '
stosd
call disasm_get_byte
dec [disasm_cur_pos]
shr al, 3
and eax, 7
call disasm_write_mmreg
mov ax, ', '
stosw
or ch, 0C0h
and ch, not 1
call disasm_readrmop
and byte [edi], 0
ret
cmovd2:
mov eax, 'movd'
stosd
mov eax, ' '
stosd
call disasm_get_byte
dec [disasm_cur_pos]
shr al, 3
and eax, 7
push eax ecx
or ch, 0C0h
and ch, not 1
call disasm_readrmop
mov ax, ', '
stosw
pop ecx eax
call disasm_write_mmreg
and byte [edi], 0
ret
 
cmovq1:
test ch, 1
jz .mm
mov eax, 'movd'
stosd
mov eax, 'qa '
stosd
jmp disasm_mmx1
.mm:
mov eax, 'movq'
stosd
mov eax, ' '
stosd
jmp disasm_mmx1
cmovq2:
test ch, 1
jz .mm
mov eax, 'movd'
stosd
mov eax, 'qa '
stosd
jmp disasm_mmx3
.mm:
mov eax, 'movq'
disasm_mmx2:
stosd
mov eax, ' '
stosd
disasm_mmx3:
or ch, 50h
call disasm_get_byte
dec [disasm_cur_pos]
push eax
call disasm_readrmop
mov ax, ', '
stosw
pop eax
shr al, 3
and eax, 7
call disasm_write_mmreg
and byte [edi], 0
ret
 
iglobal
mmx_cmds:
db 0x60,'unpcklbw'
db 0x61,'unpcklwd'
db 0x62,'unpckldq'
db 0x63,'packsswb'
db 0x64,'pcmpgtb '
db 0x65,'pcmpgtw '
db 0x66,'pcmpgtd '
db 0x67,'packuswb'
db 0x68,'unpckhbw'
db 0x69,'unpckhwd'
db 0x6A,'unpckhdq'
db 0x6B,'packssdw'
db 0x74,'pcmpeqb '
db 0x75,'pcmpeqw '
db 0x76,'pcmpeqd '
db 0xD4,'paddq '
db 0xD5,'pmullw '
db 0xD8,'psubusb '
db 0xD9,'psubusw '
db 0xDA,'pminub '
db 0xDB,'pand '
db 0xDC,'paddusb '
db 0xDD,'paddusw '
db 0xDE,'pmaxub '
db 0xDF,'pandn '
db 0xE0,'pavgb '
db 0xE3,'pavgw '
db 0xE4,'pmulhuw '
db 0xE5,'pmulhw '
db 0xE8,'psubsb '
db 0xE9,'psubsw '
db 0xEA,'pminsw '
db 0xEB,'por '
db 0xEC,'paddsb '
db 0xED,'paddsw '
db 0xEE,'pmaxsw '
db 0xEF,'pxor '
db 0xF4,'pmuludq '
db 0xF5,'pmaddwd '
db 0xF6,'psadbw '
db 0xF8,'psubb '
db 0xF9,'psubw '
db 0xFA,'psubd '
db 0xFB,'psubq '
db 0xFC,'paddb '
db 0xFD,'paddw '
db 0xFE,'paddd '
endg
cpcmn:
mov esi, mmx_cmds
@@:
cmp al, [esi]
jz @f
add esi, 9
jmp @b
@@:
inc esi
mov al, 'p'
cmp byte [esi], al
jz @f
stosb
@@:
movsd
movsd
cmp byte [edi-1], ' '
jz @f
mov al, ' '
stosb
@@:
 
disasm_mmx1:
or ch, 50h
call disasm_get_byte
dec [disasm_cur_pos]
shr al, 3
and eax, 7
call disasm_write_mmreg
mov ax, ', '
stosw
call disasm_readrmop
cmp word [disasm_string], 'cm'
jz .cmp
and byte [edi], 0
ret
.cmp:
call disasm_get_byte
and eax, 7
mov dx, 'eq'
dec eax
js @f
mov dx, 'lt'
jz @f
mov dh, 'e'
dec eax
jnz .no2
@@:
xchg dx, word [disasm_string+3]
mov word [disasm_string+5], dx
and byte [edi], 0
ret
.no2:
dec eax
jnz @f
add edi, 2
push edi
lea esi, [edi-3]
lea ecx, [esi-(disasm_string+8)+2]
std
rep movsb
cld
mov cx, word [esi-3]
mov dword [esi-3], 'unor'
mov byte [esi+1], 'd'
mov word [esi+2], cx
pop edi
and byte [edi+1], 0
ret
@@:
mov edx, 'neq'
dec eax
jz @f
mov edx, 'nlt'
dec eax
jz @f
mov edx, 'nle'
dec eax
jz @f
mov edx, 'ord'
@@:
push edi
lea esi, [edi-1]
lea ecx, [esi-(disasm_string+8)+2]
std
rep movsb
cld
mov cx, word [esi-3]
mov dword [esi-3], edx
mov word [esi], cx
pop edi
and byte [edi+1], 0
ret
 
cpsrlw:
mov eax, 'psrl'
jmp @f
cpsraw:
mov eax, 'psra'
jmp @f
cpsllw:
mov eax, 'psll'
@@:
stosd
mov eax, 'w '
stosd
jmp disasm_mmx1
cpsrld:
mov eax, 'psrl'
jmp @f
cpsrad:
mov eax, 'psra'
jmp @f
cpslld:
mov eax, 'psll'
@@:
stosd
mov eax, 'd '
stosd
jmp disasm_mmx1
cpsrlq:
mov eax, 'psrl'
jmp @f
cpsllq:
mov eax, 'psll'
@@:
stosd
mov eax, 'q '
stosd
jmp disasm_mmx1
 
csse1:
iglobal
sse_cmds1:
db 0x2F,4,'comi'
db 0x54,3,'and'
db 0x55,4,'andn'
db 0x58,3,'add'
db 0xC2,3,'cmp'
endg
mov esi, sse_cmds1+1
.1:
@@:
movzx edx, byte [esi]
cmp al, [esi-1]
jz @f
lea esi, [esi+edx+2]
jmp @b
@@:
push ecx
mov ecx, edx
inc esi
rep movsb
pop ecx
mov al, 's'
cmp byte [edi-1], 'i'
jz @f
mov al, 'p'
@@:
stosb
mov al, 'd'
test ch, 1
jnz @f
mov al, 's'
@@:
stosb
push ecx
push 5
pop ecx
sub ecx, edx
adc ecx, 1
mov al, ' '
rep stosb
pop ecx
or ch, 1 ; force XMM reg
jmp disasm_mmx1
 
csse2:
iglobal
sse_cmds2:
db 0xD0,6,'addsub'
db 0,0
endg
test ch, 1
jz cerr
mov esi, sse_cmds2+1
jmp csse1.1
 
cpshift:
mov dl, al
mov ax, 'ps'
stosw
call disasm_get_byte
push eax
and al, 0xC0
cmp al, 0xC0
jnz .pop_cunk
pop eax
push eax
shr al, 3
and eax, 7
cmp al, 2
jz .rl
cmp al, 4
jz .ra
cmp al, 6
jz .ll
.pop_cunk:
pop eax
jmp cunk
.ll:
mov ax, 'll'
jmp @f
.rl:
mov ax, 'rl'
jmp @f
.ra:
cmp dl, 0x73
jz .pop_cunk
mov ax, 'ra'
@@:
stosw
mov al, 'w'
cmp dl, 0x71
jz @f
mov al, 'd'
cmp dl, 0x72
jz @f
mov al, 'q'
@@:
stosb
mov ax, ' '
stosw
stosb
pop eax
and eax, 7
call disasm_write_mmreg
mov ax, ', '
stosw
xor eax, eax
call disasm_get_byte
call disasm_write_num
and byte [edi], 0
ret
 
iglobal
grp15c1 dq 'fxsave ','fxrstor ','ldmxcsr ','stmxcsr ',0,0,0,'clflush '
endg
cgrp15:
call disasm_get_byte
cmp al, 0xC0
jae cunk
shr al, 3
and eax, 7
mov edx, eax
mov eax, dword [grp15c1+eax*8]
test eax, eax
jz cerr
dec [disasm_cur_pos]
stosd
mov eax, dword [grp15c1+4+edx*8]
stosd
or ch, 40h
call disasm_readrmop
and byte [edi], 0
ret
 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; DATA ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5689,6 → 2354,7
 
caption_str db 'Kolibri Debugger',0
caption_len = $ - caption_str
 
begin_str db 'Kolibri Debugger, version 0.32',10
db 'Hint: type "help" for help, "quit" for quit'
newline db 10,0
5701,6 → 2367,12
db 0
dd aBreakpoints, 0, 0, help_breaks_msg
db 0
 
;-----------------------------------------------------------------------------
; Commands format definitions
 
; TODO: make it with macros
 
; flags field:
; &1: command may be called without parameters
; &2: command may be called with parameters
5726,9 → 2398,9
dd aResume, OnResume, ResumeSyntax, ResumeHelp
db 0Bh
dd aStep, OnStep, StepSyntax, StepHelp
db 9
db 0Bh
dd aProceed, OnProceed, ProceedSyntax, ProceedHelp
db 9
db 0Bh
dd aCalc, OnCalc, CalcSyntax, CalcHelp
db 0Eh
dd aDump, OnDump, DumpSyntax, DumpHelp
5760,6 → 2432,10
dd aLoadSymbols, OnLoadSymbols, LoadSymbolsSyntax, LoadSymbolsHelp
db 0Ah
dd 0
 
;-----------------------------------------------------------------------------
; Help messages for commands groups
 
aHelp db 5,'help',0
_aH db 2,'h',0
HelpHelp db 'Help on specified function',10
5769,6 → 2445,9
db '"help control" - display list of control commands',10
db '"help data" - display list of commands concerning data',10
db '"help breakpoints" - display list of commands concerning breakpoints',10,0
 
; Control commands group
 
aControl db 8,'control',0
help_control_msg db 'List of control commands:',10
db 'h = help - help',10
5780,9 → 2459,12
db 'detach - detach from debugging program',10
db 'stop - suspend execution of debugging program',10
db 'g [<expression>] - go on (resume execution of debugging program)',10
db 's = <Ctrl+F7> - program step',10
db 'p = <Ctrl+F8> - program wide step',10
db 's [<num>] - program step, also <Ctrl+F7>',10
db 'p [<num>] - program wide step, also <Ctrl+F8>',10
db 'unpack - try to bypass unpacker code (heuristic)',10,0
 
; Data commands group
 
aData db 5,'data',0
help_data_msg db 'List of data commands:',10
db '? <expression> - calculate value of expression',10
5790,6 → 2472,9
db 'u [<expression>] - unassemble instructions at given address',10
db 'r <register> <expression> or',10
db 'r <register>=<expression> - set register value',10,0
; Breakpoints commands group
 
aBreakpoints db 12,'breakpoints',0
help_breaks_msg db 'List of breakpoints commands:',10
db 'bp <expression> - set breakpoint on execution',10
5799,6 → 2484,9
db 'bd <number>... - disable breakpoint',10
db 'be <number>... - enable breakpoint',10,0
 
;-----------------------------------------------------------------------------
; Individual command help messages
 
aQuit db 5,'quit',0
QuitHelp db 'Quit from debugger',10
QuitSyntax db 'Usage: quit',10,0
5830,11 → 2518,11
 
aStep db 2,'s',0
StepHelp db 'Make step in debugged program',10
StepSyntax db 'Usage: s',10,0
StepSyntax db 'Usage: s [<number>]',10,0
 
aProceed db 2,'p',0
ProceedHelp db 'Make wide step in debugged program (step over CALL, REPxx, LOOP)',10
ProceedSyntax db 'Usage: p',10,0
ProceedSyntax db 'Usage: p [<number>]',10,0
 
aDump db 2,'d',0
DumpHelp db 'Dump data of debugged program',10
5847,14 → 2535,12
 
aUnassemble db 2,'u',0
UnassembleHelp db 'Unassemble',10
UnassembleSyntax:
db 'Usage: u <expression> - unassemble instructions at specified address',10
UnassembleSyntax db 'Usage: u <expression> - unassemble instructions at specified address',10
db ' or: u - continue current unassemble screen',10,0
 
aReg db 2,'r',0
RHelp db 'Set register value',10
RSyntax:
db 'Usage: r <register> <expression>',10
RSyntax db 'Usage: r <register> <expression>',10
db ' or: r <register>=<expression> - set value of <register> to <expression>',10,0
 
aBp db 3,'bp',0
5907,6 → 2593,9
 
aUnknownCommand db 'Unknown command',10,0
 
;-----------------------------------------------------------------------------
; Error messages
 
load_err_msg db 'Cannot load program. ',0
unk_err_msg db 'Unknown error code -%4X',10,0
aCannotLoadFile db 'Cannot load file. ',0
5955,6 → 2644,10
NoPrgLoaded_len = $ - NoPrgLoaded_str
aRunning db 'Running'
aPaused db 'Paused'
aMain db '[ CPU ]'
aSSE db '[ SSE ]'
aAVX db '[ AVX ]'
aMSR db '[ MSR ]'
aPoint db 0x1C
aMinus db '-'
aColon db ':'
5980,6 → 2673,10
mtappack_name db 'mtappack',0
flags db 'CPAZSDO'
flags_bits db 0,2,4,6,7,10,11
 
;-----------------------------------------------------------------------------
; Registers strings
 
regs_strs:
db 'EAX='
db 'EBX='
5991,80 → 2688,51
db 'ESP='
db 'EIP='
db 'EFLAGS='
fpu_strs:
db 'ST0='
db 'ST1='
db 'ST2='
db 'ST3='
db 'ST4='
db 'ST5='
db 'ST6='
db 'ST7='
mmx_strs:
db 'MM0='
db 'MM1='
db 'MM2='
db 'MM3='
db 'MM4='
db 'MM5='
db 'MM6='
db 'MM7='
sse_strs:
db '-XMM0-'
db '-XMM1-'
db '-XMM2-'
db '-XMM3-'
db '-XMM4-'
db '-XMM5-'
db '-XMM6-'
db '-XMM7-'
avx_strs:
db '-YMM0-'
db '-YMM1-'
db '-YMM2-'
db '-YMM3-'
db '-YMM4-'
db '-YMM5-'
db '-YMM6-'
db '-YMM7-'
 
debuggee_pid dd 0
bSuspended db 0
bAfterGo db 0
temp_break dd 0
reg_mode db 1
 
disasm_table_1:
dd cop22, cop22, cop22, cop22, cop21, cop21, cop0, cop0 ; 0x
dd cop22, cop22, cop22, cop22, cop21, cop21, cop0, cF
dd cop22, cop22, cop22, cop22, cop21, cop21, cop0, cop0 ; 1x
dd cop22, cop22, cop22, cop22, cop21, cop21, cop0, cop0
dd cop22, cop22, cop22, cop22, cop21, cop21, cseges,cop0 ; 2x
dd cop22, cop22, cop22, cop22, cop21, cop21, csegcs,cop0
dd cop22, cop22, cop22, cop22, cop21, cop21, csegss,cop0 ; 3x
dd cop22, cop22, cop22, cop22, cop21, cop21, csegds,cop0
dd cinc1, cinc1, cinc1, cinc1, cinc1, cinc1, cinc1, cinc1 ; 4x
dd cdec1, cdec1, cdec1, cdec1, cdec1, cdec1, cdec1, cdec1
dd cpush1,cpush1,cpush1,cpush1,cpush1,cpush1,cpush1,cpush1 ; 5x
dd cpop1, cpop1, cpop1, cpop1, cpop1, cpop1, cpop1, cpop1
dd cop0, cop0, cbound,carpl, csegfs,cseggs,c66, c67 ; 6x
dd cpush21,cimul1,cpush22,cimul1,cunk,cunk, cunk, cunk
dd cjcc1, cjcc1, cjcc1, cjcc1, cjcc1, cjcc1, cjcc1, cjcc1 ; 7x
dd cjcc1, cjcc1, cjcc1, cjcc1, cjcc1, cjcc1, cjcc1, cjcc1
dd cop23, cop23, cop23, cop23, cop22, cop22, cop22, cop22 ; 8x
dd cop22, cop22, cop22, cop22, cunk, cop22, cunk, cpop2
dd cop0, cxchg1,cxchg1,cxchg1,cxchg1,cxchg1,cxchg1,cxchg1 ; 9x
dd ccbw, ccwd, ccallf,cop0, cop0, cop0, cop0, cop0
dd cmov3, cmov3, cmov3, cmov3, cop0, cop0, cop0, cop0 ; Ax
dd cop21, cop21, cop0, cop0, cop0, cop0, cop0, cop0
dd cmov11,cmov11,cmov11,cmov11,cmov11,cmov11,cmov11,cmov11 ; Bx
dd cmov12,cmov12,cmov12,cmov12,cmov12,cmov12,cmov12,cmov12
dd cshift1,cshift1,cret2,cop0, cunk, cunk, cmov2, cmov2 ; Cx
dd center,cop0, cunk, cunk, cop0, cint, cunk, cunk
dd cshift2,cshift2,cshift3,cshift3,caam,caad,cunk, cxlat ; Dx
dd cD8, cD9, cDA, cDB, cDC, cDD, cDE, cDF
dd cloopnz,cloopz,cloop,cjcxz, cunk, cunk, cunk, cunk ; Ex
dd ccall1,cjmp1, cunk, cjmp2, cunk, cunk, cunk, cunk
dd clock, cunk, crepnz,crep, cunk, cop0, cop1, cop1 ; Fx
dd cop0, cop0, cop0, cop0, cop0, cop0, cop1, cop1
include 'disasm_tbl.inc'
 
disasm_table_2:
dd cunk, cunk, cunk, cunk, cunk, cop0_F,cop0_F,cunk ; 0x
dd cunk, cunk, cunk, cunk, cunk, cunk, cunk, cunk
dd cunk, cunk, cunk, cunk, cunk, cunk, cunk, cunk ; 1x
dd cunk, cunk, cunk, cunk, cunk, cunk, cunk, cunk
dd cunk, cunk, cunk, cunk, cunk, cunk, cunk, cunk ; 2x
dd cunk, cunk, cunk, cunk, cunk, cunk, cunk, csse1
dd cunk, crdtsc,cunk, cunk, cop0_F,cunk, cunk, cunk ; 3x
dd cunk, cunk, cunk, cunk, cunk, cunk, cunk, cunk
dd cmovcc,cmovcc,cmovcc,cmovcc,cmovcc,cmovcc,cmovcc,cmovcc ; 4x
dd cmovcc,cmovcc,cmovcc,cmovcc,cmovcc,cmovcc,cmovcc,cmovcc
dd cunk, cunk, cunk, cunk, csse1, csse1, cunk, cunk ; 5x
dd csse1, cunk, cunk, cunk, cunk, cunk, cunk, cunk
dd cpcmn, cpcmn, cpcmn, cpcmn, cpcmn, cpcmn, cpcmn, cpcmn ; 6x
dd cpcmn, cpcmn, cpcmn, cpcmn, cunk, cunk, cmovd1,cmovq1
dd cunk, cpshift,cpshift,cpshift,cpcmn,cpcmn,cpcmn,cemms ; 7x
dd cunk, cunk, cunk, cunk, cunk, cunk, cmovd2,cmovq2
dd cjcc2, cjcc2, cjcc2, cjcc2, cjcc2, cjcc2, cjcc2, cjcc2 ; 8x
dd cjcc2, cjcc2, cjcc2, cjcc2, cjcc2, cjcc2, cjcc2, cjcc2
dd csetcc,csetcc,csetcc,csetcc,csetcc,csetcc,csetcc,csetcc ; 9x
dd csetcc,csetcc,csetcc,csetcc,csetcc,csetcc,csetcc,csetcc
dd cunk, cunk, ccpuid,cbtx2, cshld, cshld, cunk, cunk ; Ax
dd cunk, cunk, cunk, cbtx2, cshrd, cshrd, cgrp15,cop22
dd ccmpxchg,ccmpxchg,cunk,cbtx2,cunk, cunk, cmovzx,cmovzx ; Bx
dd cunk, cunk, cbtx1, cbtx2, cbsf, cbsr, cmovsx,cmovsx
dd cunk, cunk, csse1, cunk, cunk, cunk, cunk, ccmpxchg8b ; Cx
dd cbswap,cbswap,cbswap,cbswap,cbswap,cbswap,cbswap,cbswap
dd csse2, cpsrlw,cpsrlw,cpsrlq,cpcmn, cpcmn, cunk, cunk ; Dx
dd cpcmn, cpcmn, cpcmn, cpcmn, cpcmn, cpcmn, cpcmn, cpcmn
dd cpcmn, cpsraw,cpsrad,cpcmn, cpcmn, cpcmn, cunk, cunk ; Ex
dd cpcmn, cpcmn, cpcmn, cpcmn, cpcmn, cpcmn, cpcmn, cpcmn
dd cunk, cpsllw,cpslld,cpsllq,cpcmn, cpcmn, cpcmn, cunk ; Fx
dd cpcmn, cpcmn, cpcmn, cpcmn, cpcmn, cpcmn, cpcmn, cunk
 
reg_table:
db 2,'al',0
db 2,'cl',1
6138,6 → 2806,8
cmdline_pos dd ?
curarg dd ?
 
cmdline_prev rb cmdline_width+1
 
was_temp_break db ?
 
dbgbufsize dd ?
6149,6 → 2819,7
needzerostart:
 
context:
 
_eip dd ?
_eflags dd ?
_eax dd ?
6159,9 → 2830,54
_ebp dd ?
_esi dd ?
_edi dd ?
 
oldcontext rb $-context
 
mmx_context:
_mm0 dq ?
_mm1 dq ?
_mm2 dq ?
_mm3 dq ?
_mm4 dq ?
_mm5 dq ?
_mm6 dq ?
_mm7 dq ?
oldmmxcontext rb $-mmx_context
 
fpu_context:
_st0 dq ?
_st1 dq ?
_st2 dq ?
_st3 dq ?
_st4 dq ?
_st5 dq ?
_st6 dq ?
_st7 dq ?
oldfpucontext rb $-fpu_context
 
sse_context:
_xmm0 dq 2 dup ?
_xmm1 dq 2 dup ?
_xmm2 dq 2 dup ?
_xmm3 dq 2 dup ?
_xmm4 dq 2 dup ?
_xmm5 dq 2 dup ?
_xmm6 dq 2 dup ?
_xmm7 dq 2 dup ?
oldssecontext rb $-sse_context
 
avx_context:
_ymm0 dq 4 dup ?
_ymm1 dq 4 dup ?
_ymm2 dq 4 dup ?
_ymm3 dq 4 dup ?
_ymm4 dq 4 dup ?
_ymm5 dq 4 dup ?
_ymm6 dq 4 dup ?
_ymm7 dq 4 dup ?
oldavxcontext rb $-avx_context
 
step_num dd 0
proc_num dd 0
dumpread dd ?
dumppos dd ?
dumpdata rb dump_height*10h
6200,3 → 2916,6
align 400h
rb 400h
used_mem:
 
; vim: ft=fasm tabstop=4
 
/programs/develop/mtdbg/parser.inc
0,0 → 1,403
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;; EXPRESSION PARSER ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
 
token_end equ 1
token_reg equ 2
token_hex equ 3
token_add equ 4
token_sub equ 5
token_mul equ 6
token_div equ 7
token_lp equ 8
token_rp equ 9
token_err equ -1
 
 
;-----------------------------------------------------------------------------
; Check if byte - some kind of instruction prefix
 
is_prefix:
cmp al, 0x64 ; fs:
jz .ret
cmp al, 0x65 ; gs:
jz .ret
cmp al, 0x66 ; use16/32
jz .ret
cmp al, 0x67 ; addr16/32
jz .ret
cmp al, 0xF0 ; lock
jz .ret
cmp al, 0xF2 ; repnz
jz .ret
cmp al, 0xF3 ; rep(z)
jz .ret
cmp al, 0x2E ; cs:
jz .ret
cmp al, 0x36 ; ss:
jz .ret
cmp al, 0x3E ; ds:
jz .ret
cmp al, 0x26 ; es:
.ret:
ret
 
;-----------------------------------------------------------------------------
; Check if byte is hex digit
 
is_hex_digit:
cmp al, '0'
jb .no
cmp al, '9'
jbe .09
cmp al, 'A'
jb .no
cmp al, 'F'
jbe .AF
cmp al, 'a'
jb .no
cmp al, 'f'
jbe .af
 
.no:
stc
ret
 
.09:
sub al, '0'
; clc
ret
 
.AF:
sub al, 'A'-10
; clc
ret
 
.af:
sub al, 'a'-10
; clc
ret
 
;-----------------------------------------------------------------------------
; Find register in the table
 
find_reg:
mov edi, reg_table
.findreg:
movzx ecx, byte [edi]
stc
jecxz .regnotfound
inc edi
push esi edi ecx
@@:
lodsb
or al, 20h
scasb
loopz @b
pop ecx edi esi
lea edi, [edi+ecx+1]
jnz .findreg
movzx edi, byte [edi-1]
add esi, ecx
 
.regnotfound:
ret
 
;-----------------------------------------------------------------------------
; Tokenize expressions
 
expr_get_token:
lodsb
cmp al, 0
jz .end_token
cmp al, ' '
jbe expr_get_token
cmp al, '+'
jz .add
cmp al, '-'
jz .sub
cmp al, '*'
jz .mul
cmp al, '/'
jz .div
cmp al, '('
jz .lp
cmp al, ')'
jnz .notsign
.rp:
mov al, token_rp
ret
.div:
mov al, token_div
ret
 
.end_token:
mov al, token_end
ret
.add:
mov al, token_add
ret
 
.sub:
mov al, token_sub
ret
 
.mul:
mov al, token_mul
ret
 
.lp:
mov al, token_lp
ret
 
.notsign:
dec esi
call find_reg
jc .regnotfound
mov al, token_reg
ret
 
.regnotfound:
; test for symbol
push esi
 
@@:
lodsb
cmp al, ' '
ja @b
push eax
mov byte [esi], 0
xchg esi, [esp+4]
call find_symbol_name
mov edi, eax
pop eax
xchg esi, [esp]
mov byte [esi], al
jc @f
add esp, 4
mov al, token_hex
ret
 
@@:
pop esi
; test for hex number
xor ecx, ecx
xor edi, edi
xor eax, eax
 
@@:
lodsb
call is_hex_digit
jc @f
shl edi, 4
or edi, eax
inc ecx
jmp @b
 
@@:
dec esi
jecxz .err
cmp ecx, 8
ja .err
mov al, token_hex
ret
 
.err:
mov al, token_err
mov esi, aParseError
ret
 
;-----------------------------------------------------------------------------
 
expr_read2:
cmp al, token_hex
jz .hex
cmp al, token_reg
jz .reg
cmp al, token_lp
jz .lp
mov al, token_err
mov esi, aParseError
ret
 
.hex:
mov ebp, edi
 
.ret:
jmp expr_get_token
 
.reg:
cmp edi, 24
jz .eip
sub edi, 4
jb .8lo
sub edi, 4
jb .8hi
sub edi, 8
jb .16
mov ebp, [_eax+edi*4]
jmp .ret
 
.16:
movzx ebp, word [_eax+(edi+8)*4]
jmp .ret
 
.8lo:
movzx ebp, byte [_eax+(edi+4)*4]
jmp .ret
 
.8hi:
movzx ebp, byte [_eax+(edi+4)*4+1]
jmp .ret
 
.eip:
mov ebp, [_eip]
jmp .ret
 
.lp:
call expr_get_token
call expr_read0
cmp al, token_err
jz @f
cmp al, token_rp
jz expr_get_token
mov al, token_err
mov esi, aParseError
 
@@:
ret
 
;-----------------------------------------------------------------------------
 
expr_read1:
call expr_read2
 
.1:
cmp al, token_mul
jz .mul
cmp al, token_div
jz .div
ret
 
.mul:
push ebp
call expr_get_token
call expr_read2
pop edx
; ebp := edx*ebp
imul ebp, edx
jmp .1
 
.div:
push ebp
call expr_get_token
call expr_read2
pop edx
; ebp := edx/ebp
test ebp, ebp
jz .div0
push eax
xor eax, eax
xchg eax, edx
div ebp
xchg eax, ebp
pop eax
jmp .1
 
.div0:
mov al, token_err
mov esi, aDivByZero
ret
 
;-----------------------------------------------------------------------------
 
expr_read0:
xor ebp, ebp
cmp al, token_add
jz .add
cmp al, token_sub
jz .sub
call expr_read1
 
.1:
cmp al, token_add
jz .add
cmp al, token_sub
jz .sub
ret
 
.add:
push ebp
call expr_get_token
call expr_read1
pop edx
; ebp := edx+ebp
add ebp, edx
jmp .1
 
.sub:
push ebp
call expr_get_token
call expr_read1
pop edx
; ebp := edx-ebp
xchg edx, ebp
sub ebp, edx
jmp .1
 
;-----------------------------------------------------------------------------
 
; in: esi->expression
; out: CF=1 if error
; CF=0 and ebp=value if ok
calc_expression:
call expr_get_token
call expr_read0
cmp al, token_end
jz .end
cmp al, token_err
jz @f
mov esi, aParseError
 
@@:
call put_message
stc
ret
 
.end:
clc
ret
 
;-----------------------------------------------------------------------------
 
get_arg:
lodsb
cmp al, ' '
ja get_arg
mov byte [esi-1], 0
cmp al, 0
jnz .skip_spaces
dec esi
 
.skip_spaces:
lodsb
cmp al, 0
jz @f
cmp al, ' '
jbe .skip_spaces
 
@@:
dec esi
ret
 
 
 
; vim: ft=fasm tabstop=4
 
/programs/develop/mtdbg/sort.inc
1,8 → 1,10
; ‘®àâ¨à®¢ª  dword'®¢ ¢ ª®«¨ç¥á⢥ ecx ¯®  ¤à¥áã edx, äã­ªæ¨ï áà ¢­¥­¨ï ¢ ebx
;  §àãè ¥â eax, ecx, esi, edi
; Sorting bunch of dwords, count = ecx, locating at address = edx,
; comparison function at ebx
; Destroy content of eax, ecx, esi, edi
sort:
jecxz .done
mov eax, ecx
 
@@:
push eax
call .restore
9,6 → 11,7
pop eax
dec eax
jnz @b
 
@@:
cmp ecx, 1
jz .done
19,6 → 22,7
mov eax, 1
call .restore
jmp @b
 
.done:
ret
 
34,7 → 38,7
.restore:
lea esi, [eax+eax]
cmp esi, ecx
ja .doner
ja .donerr
push esi
mov esi, [edx+esi*4-4]
mov edi, [edx+eax*4-4]
42,13 → 46,14
pop esi
ja .need_xchg
cmp esi, ecx
jae .doner
jae .donerr
push esi
mov esi, [edx+esi*4]
mov edi, [edx+eax*4-4]
call ebx
pop esi
jbe .doner
jbe .donerr
 
.need_xchg:
cmp esi, ecx
jz .do_xchg
58,10 → 63,15
call ebx
pop esi
sbb esi, -1
 
.do_xchg:
mov edi, eax
call .exchange
mov eax, esi
jmp .restore
.doner:
 
.donerr:
ret
 
; vim: ft=fasm tabstop=4