diff --git a/programs/develop/mtdbg/README b/programs/develop/mtdbg/README new file mode 100644 index 0000000000..e4cb2cbf2e --- /dev/null +++ b/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 + diff --git a/programs/develop/mtdbg/cmd.inc b/programs/develop/mtdbg/cmd.inc new file mode 100644 index 0000000000..dea69efd0e --- /dev/null +++ b/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 + diff --git a/programs/develop/mtdbg/disasm.inc b/programs/develop/mtdbg/disasm.inc new file mode 100644 index 0000000000..7f3292a0a5 --- /dev/null +++ b/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 + diff --git a/programs/develop/mtdbg/disasm_tbl.inc b/programs/develop/mtdbg/disasm_tbl.inc new file mode 100644 index 0000000000..13a735ca9a --- /dev/null +++ b/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 + diff --git a/programs/develop/mtdbg/gui.inc b/programs/develop/mtdbg/gui.inc new file mode 100644 index 0000000000..eb74d2916c --- /dev/null +++ b/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 %X + .format: + lodsb ; get + 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 + diff --git a/programs/develop/mtdbg/mtdbg.asm b/programs/develop/mtdbg/mtdbg.asm index 27b3f8362a..fc5bf787c5 100644 --- a/programs/develop/mtdbg/mtdbg.asm +++ b/programs/develop/mtdbg/mtdbg.asm @@ -1,5687 +1,2352 @@ format binary include '../../macros.inc' use32 - db 'MENUET01' - dd 1 - dd start - dd i_end - dd used_mem - dd used_mem - dd i_param - dd 0 + db 'MENUET01' + dd 1 + dd start + dd i_end + dd used_mem + dd used_mem + 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) - -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 command in list find_cmd: ; all commands are case-insensitive - push edi -.x4: - mov al, [edi] - cmp al, 0 - jz .x5 - cmp al, 'A' - jb @f - cmp al, 'Z' - ja @f - or al, 20h -@@: - stosb - jmp .x4 -.x5: -; find command - pop edi -.x6: - cmp dword [esi], 0 - jz .x7 - push esi - mov esi, [esi] - lodsb - movzx ecx, al - push edi - repz cmpsb - pop edi - pop esi - jz .x8 - add esi, 17 - jmp .x6 -.x7: - stc -.x8: - ret + push edi -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 + .x4: + mov al, [edi] + cmp al, 0 + jz .x5 + cmp al, 'A' + jb @f + cmp al, 'Z' + ja @f + or al, 20h -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 + @@: + stosb + jmp .x4 -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 + ; find command + .x5: + pop edi -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 %X - lodsb ; get - 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 + .x6: + cmp dword [esi], 0 + jz .x7 + push esi + mov esi, [esi] + lodsb + movzx ecx, al + push edi + repz cmpsb + pop edi + pop esi + jz .x8 + add esi, 17 + jmp .x6 -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 + .x7: + stc -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 + .x8: + ret ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; DEBUGGING ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -OnHelp: - mov esi, help_msg - mov edi, [curarg] - cmp byte [edi], 0 - jz .x - mov esi, help_groups - call find_cmd - jc .nocmd - mov esi, [esi+12] -.x: - jmp put_message -.nocmd: - mov esi, aUnknownCommand - jmp .x +;----------------------------------------------------------------------------- +; Help event +OnHelp: + mov esi, help_msg + mov edi, [curarg] + cmp byte [edi], 0 + jz .x + mov esi, help_groups + 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 + 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 - ret + ;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 - ret + ;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: - mov edi, dumpdata - mov esi, [edi-4] - mov edx, dump_height*10h - mov ecx, edx - xor eax, eax - push edi - rep stosb - pop edi - mov ecx, [debuggee_pid] - mov al, 69 - push 6 - pop ebx - mcall - 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 -restore_from_breaks: + mov edi, dumpdata + mov esi, [edi-4] + mov edx, dump_height*10h + mov ecx, edx + xor eax, eax + push edi + rep stosb + pop edi + ;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 - mov ebx, breakpoints -@@: - test byte [ebx+4], 1 - jz .cont ; ignore invalid - test byte [ebx+4], 2 or 8 - jnz .cont ; ignore disabled and memory breaks - mov ecx, [ebx] - sub ecx, esi - cmp ecx, eax - jae .cont - mov dl, [ebx+5] - mov [edi+ecx], dl -.cont: - add ebx, 6 - cmp ebx, breakpoints+breakpoints_n*6 - jb @b - ret +restore_from_breaks: + mov ebx, breakpoints + + @@: + test byte [ebx+4], 1 + jz .cont ; ignore invalid + test byte [ebx+4], 2 or 8 + jnz .cont ; ignore disabled and memory breaks + mov ecx, [ebx] + sub ecx, esi + cmp ecx, eax + jae .cont + mov dl, [ebx+5] + mov [edi+ecx], dl + + .cont: + add ebx, 6 + cmp ebx, breakpoints+breakpoints_n*6 + jb @b + ret + +;----------------------------------------------------------------------------- +; Load executable event OnLoad: - mov esi, [curarg] + mov esi, [curarg] + OnLoadInit: - mov edi, loadname - or [prgname_len], -1 - mov [prgname_ptr], edi -.copyname: - lodsb - stosb - inc [prgname_len] - cmp al, '/' - jnz @f - or [prgname_len], -1 - mov [prgname_ptr], edi -@@: - cmp al, ' ' - ja .copyname - mov byte [edi-1], 0 - and [load_params], 0 - dec esi - call skip_spaces - cmp al, 0 - jz @f - mov [load_params], esi -@@: - and [dumppos], 0 - mov ecx, [symbols] - jecxz do_reload - mcall 68, 13 - and [symbols], 0 - and [num_symbols], 0 + mov edi, loadname + or [prgname_len], -1 + mov [prgname_ptr], edi + + .copyname: + lodsb + stosb + inc [prgname_len] + cmp al, '/' + jnz @f + or [prgname_len], -1 + mov [prgname_ptr], edi + + @@: + cmp al, ' ' + ja .copyname + mov byte [edi-1], 0 + and [load_params], 0 + dec esi + call get_arg.skip_spaces + cmp al, 0 + jz @f + mov [load_params], esi + + @@: + and [dumppos], 0 + mov ecx, [symbols] + jecxz do_reload + 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 - mov [dbgwnd], eax - xchg ecx, eax - push 70 - pop eax - mov ebx, fn70_load_block - mcall - test eax, eax - jns .load_ok -.load_err: - push eax - mov esi, load_err_msg - call put_message - pop eax - not eax - cmp eax, 0x20 - jae .unk_err - mov esi, [load_err_msgs+eax*4] - test esi, esi - jnz put_message -.unk_err: - mov esi, unk_err_msg - inc eax - push eax - call put_message_nodraw - jmp draw_messages -.load_ok: - mov [debuggee_pid], eax - mov [bSuspended], 1 - push ecx - call get_context - mov edi, oldcontext - mov ecx, 10 - rep movsd -; activate debugger window - pop ecx - mov bl, 3 - push 18 - pop eax - mcall - call redraw_title - call redraw_registers - call get_dump - call redraw_dump - call update_disasm_eip_force - mov esi, load_succ_msg - push [debuggee_pid] - call put_message_nodraw - call draw_messages -; try to load symbols - mov esi, loadname - mov edi, symbolsfile - push edi -@@: - lodsb - stosb - test al, al - jnz @b - lea ecx, [edi-1] -@@: - dec edi - cmp edi, symbolsfile - jb @f - cmp byte [edi], '/' - jz @f - cmp byte [edi], '.' - jnz @b - mov ecx, edi -@@: - mov dword [ecx], '.dbg' - mov byte [ecx+4], 0 - 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 - mov edi, ebp - push 3 - pop ecx - repz cmpsb - jnz .not_mxp_nrv - cmpsb - mov cl, mxp_nrv_sig_size-4 - repz cmpsb - mov esi, mxp_nrv_name - jz .packed -.not_mxp_nrv: - mov esi, mxp_sig - mov edi, ebp - mov cl, mxp_sig_size - repz cmpsb - mov esi, mxp_name - jz .packed -.not_mxp: - mov esi, mxp_lzo_sig1 - mov edi, ebp - mov cl, mxp_lzo_sig1_size - repz cmpsb - mov esi, mxp_lzo_name - jz .packed - mov esi, mxp_lzo_sig2 - mov edi, ebp - mov cl, 8 - repz cmpsb - jnz .not_mxp_lzo - cmpsb - mov cl, mxp_lzo_sig2_size - 9 - repz cmpsb - mov esi, mxp_lzo_name - jz .packed -.not_mxp_lzo: - mov esi, mtappack_name - cmp dword [ebp], 0xBF5E246A - jnz .not_mtappack - cmp dword [ebp+8], 0xEC4E8B57 - jnz .not_mtappack1 - cmp dword [ebp+12], 0x8D5EA4F3 - jnz .not_mtappack1 - cmp byte [ebp+12h], 0xE9 - jz .packed -.not_mtappack1: - cmp word [ebp+8], 0xB957 - jnz .not_mtappack - cmp dword [ebp+14], 0x575EA4F3 - 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 - call put_message_nodraw - pop esi - call put_message_nodraw - mov esi, aPacked2 - call put_message - call hide_cursor - push 40 - pop eax - push 7 - pop ebx - mcall -.wait: - push 10 - pop eax - mcall - dec eax - jz .redraw - dec eax - jz .key - or eax, -1 - mcall -.redraw: - call draw_window - call hide_cursor - jmp .wait -.key: - mov al, 2 - mcall - cmp ah, 'y' - jz .yes - cmp ah, 'Y' - jz .yes - cmp ah, 0xD - jz .yes - cmp ah, 'n' - jz .no - cmp ah, 'N' - jnz .wait -.no: - push 40 - pop eax - mov ebx, 0x107 - mcall - call draw_cursor - mov esi, aN_str - jmp put_message -.yes: - push 40 - pop eax - mov ebx, 0x107 - mcall - call draw_cursor - mov esi, aY_str - call put_message - call OnUnpack - ret + ;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 70, fn70_load_block + test eax, eax + jns .load_ok + + .load_err: + push eax + mov esi, load_err_msg + call put_message + pop eax + not eax + cmp eax, 0x20 + jae .unk_err + mov esi, [load_err_msgs+eax*4] + test esi, esi + jnz put_message + + .unk_err: + mov esi, unk_err_msg + inc eax + push eax + call put_message_nodraw + jmp draw_messages + + .load_ok: + mov [debuggee_pid], eax + mov [bSuspended], 1 + push ecx + call get_context + mov edi, oldcontext + mov ecx, 10 + rep movsd + + ; activate debugger window + pop ecx + ;mov bl, 3 + ;push 18 + ;pop eax + mcall 18, 3 + call redraw_title + call draw_registers.redraw + ; read and draw dump of memory + call get_dump + call draw_dump.redraw + call update_disasm_eip_force + mov esi, load_succ_msg + push [debuggee_pid] + call put_message_nodraw + call draw_messages + ; try to load symbols + mov esi, loadname + mov edi, symbolsfile + push edi + + @@: + lodsb + stosb + test al, al + jnz @b + lea ecx, [edi-1] + + @@: + dec edi + cmp edi, symbolsfile + jb @f + cmp byte [edi], '/' + jz @f + cmp byte [edi], '.' + jnz @b + mov ecx, edi + + @@: + mov dword [ecx], '.dbg' + mov byte [ecx+4], 0 + 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 + mov edi, ebp + push 3 + pop ecx + repz cmpsb + jnz .not_mxp_nrv + cmpsb + mov cl, mxp_nrv_sig_size-4 + repz cmpsb + mov esi, mxp_nrv_name + jz .packed + + .not_mxp_nrv: + mov esi, mxp_sig + mov edi, ebp + mov cl, mxp_sig_size + repz cmpsb + mov esi, mxp_name + jz .packed + + .not_mxp: + mov esi, mxp_lzo_sig1 + mov edi, ebp + mov cl, mxp_lzo_sig1_size + repz cmpsb + mov esi, mxp_lzo_name + jz .packed + mov esi, mxp_lzo_sig2 + mov edi, ebp + mov cl, 8 + repz cmpsb + jnz .not_mxp_lzo + cmpsb + mov cl, mxp_lzo_sig2_size - 9 + repz cmpsb + mov esi, mxp_lzo_name + jz .packed + + .not_mxp_lzo: + mov esi, mtappack_name + cmp dword [ebp], 0xBF5E246A + jnz .not_mtappack + cmp dword [ebp+8], 0xEC4E8B57 + jnz .not_mtappack1 + cmp dword [ebp+12], 0x8D5EA4F3 + jnz .not_mtappack1 + cmp byte [ebp+12h], 0xE9 + jz .packed + + .not_mtappack1: + cmp word [ebp+8], 0xB957 + jnz .not_mtappack + cmp dword [ebp+14], 0x575EA4F3 + 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 + call put_message_nodraw + pop esi + call put_message_nodraw + mov esi, aPacked2 + call put_message + call hide_cursor + ;push 40 + ;pop eax + ;push 7 + ;pop ebx + mcall 40, 7 + + .wait: + ;push 10 + ;pop eax + mcall 10 + dec eax + jz .redraw + dec eax + jz .key + or eax, -1 + mcall + + .redraw: + call draw_window + call hide_cursor + jmp .wait + + .key: + mov al, 2 + mcall + cmp ah, 'y' + jz .yes + cmp ah, 'Y' + jz .yes + cmp ah, 0xD + jz .yes + cmp ah, 'n' + jz .no + cmp ah, 'N' + jnz .wait + + .no: + ;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 40, 0x107 + call draw_cursor + mov esi, aY_str + call put_message + call OnUnpack + ret + +;----------------------------------------------------------------------------- +; Searching signatures mxp_nrv_sig: - xor eax, eax - mov ecx, 0x95 ; 0xA1 for programs with parameters - mov [eax], ecx - add ecx, [eax+24h] - push 40h - pop esi - mov edi, [eax+20h] - push edi - rep movsb - jmp dword [esp] - pop esi - add esi, [eax] - xor edi, edi + xor eax, eax + mov ecx, 0x95 ; 0xA1 for programs with parameters + mov [eax], ecx + add ecx, [eax+24h] + push 40h + pop esi + mov edi, [eax+20h] + push edi + rep movsb + jmp dword [esp] + pop esi + add esi, [eax] + xor edi, edi + mxp_nrv_sig_size = $ - mxp_nrv_sig mxp_sig: - mov ecx, 1CBh - push 46h - pop esi - mov edi, [20h] - rep movsb - mov ecx, [24h] - rep movsb - jmp dword [20h] - mov eax, [20h] - add eax, 1CBh - push eax - push dword [24h] - push 0 - push 8 - call $+0x25 + mov ecx, 1CBh + push 46h + pop esi + mov edi, [20h] + rep movsb + mov ecx, [24h] + rep movsb + jmp dword [20h] + mov eax, [20h] + add eax, 1CBh + push eax + push dword [24h] + push 0 + push 8 + call $+0x25 + mxp_sig_size = $ - mxp_sig mxp_lzo_sig1: - xor eax, eax - mov ebp, 0FFh - mov ecx, 175h - mov [eax], ecx - add ecx, [eax+24h] - push 45h - pop esi - mov edi, [eax+20h] - push edi - rep movsb - jmp dword [esp] - pop ebx - add ebx, [eax] - xor edi, edi - cmp byte [ebx], 11h - jbe $+0x1A + xor eax, eax + mov ebp, 0FFh + mov ecx, 175h + mov [eax], ecx + add ecx, [eax+24h] + push 45h + pop esi + mov edi, [eax+20h] + push edi + rep movsb + jmp dword [esp] + pop ebx + add ebx, [eax] + 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 - mov ecx, 188h ; or 177h - mov [eax], ecx - add ecx, [eax+24h] - push 44h - pop esi - mov edi, [eax+20h] - rep movsb - jmp dword [eax+20h] - mov ebx, [eax+20h] - add ebx, [eax] + xor eax, eax + mov ebp, 0FFh + mov ecx, 188h ; or 177h + mov [eax], ecx + add ecx, [eax+24h] + push 44h + pop esi + mov edi, [eax+20h] + rep movsb + 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 - mov esi, need_debuggee - cmp byte [loadname], 0 - jnz do_reload - jz put_message + cmp [debuggee_pid], 0 + jnz terminate_reload + mov esi, need_debuggee + cmp byte [loadname], 0 + jnz do_reload + jz put_message + +; TODO: make it local terminate_reload: - mov [bReload], 1 + mov [bReload], 1 + +;----------------------------------------------------------------------------- +; Terminate process event + OnTerminate: - mov ecx, [debuggee_pid] - push 8 - pop ebx - push 69 - pop eax - mcall - ret + ;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 - call get_new_context - call get_dump - call redraw_title - call redraw_registers - call redraw_dump - call update_disasm_eip - ret + mov [bSuspended], 1 + call get_new_context + call get_dump + call redraw_title + 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 - call AfterSuspend - mov esi, aSuspended - jmp put_message + ;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 [bSuspended], 0 - ret + ;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 - jz GoOn - call calc_expression - jc .ret - mov eax, ebp - push eax - call find_enabled_breakpoint - pop eax - jz GoOn - mov bl, 5 ; valid enabled one-shot - call add_breakpoint - jnc GoOn - mov esi, aBreakpointLimitExceeded - call put_message -.ret: - ret + mov esi, [curarg] + cmp byte [esi], 0 + jz GoOn + call calc_expression + jc .ret + mov eax, ebp + push eax + call find_enabled_breakpoint + pop eax + jz GoOn + mov bl, 5 ; valid enabled one-shot + call add_breakpoint + jnc GoOn + mov esi, aBreakpointLimitExceeded + call put_message + + .ret: + ret + GoOn: -; test for enabled breakpoint at eip - mov eax, [_eip] - call find_enabled_breakpoint - jnz .nobreak -; temporarily disable breakpoint, make step, enable breakpoint, continue - inc eax - mov [temp_break], eax - mov [bAfterGo], 1 - dec eax - call disable_breakpoint - call get_context - or byte [_eflags+1], 1 ; set TF - call set_context - and byte [_eflags+1], not 1 - call DoResume - ret -.nobreak: - call DoResume - call redraw_title - call redraw_registers - call redraw_dump - ret + ; test for enabled breakpoint at eip + mov eax, [_eip] + call find_enabled_breakpoint + jnz .nobreak + ; temporarily disable breakpoint, make step, enable breakpoint, continue + inc eax + mov [temp_break], eax + mov [bAfterGo], 1 + dec eax + call disable_breakpoint + call get_context + or byte [_eflags+1], 1 ; set TF + call set_context + and byte [_eflags+1], not 1 + call DoResume + ret + + .nobreak: + call DoResume + call redraw_title + 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 - and [debuggee_pid], 0 - call redraw_title - call redraw_registers - call redraw_dump - call free_symbols - mov esi, aContinued - jmp put_message + ;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 draw_registers.redraw + call draw_dump.redraw + call free_symbols + mov esi, aContinued + jmp put_message after_go_exception: - push eax - mov eax, [temp_break] - dec eax - push esi - call enable_breakpoint -; in any case, clear TF and RF - call get_new_context - and [_eflags], not 10100h ; clear TF,RF - call set_context - xor edx, edx - mov [temp_break], edx - xchg dl, [bAfterGo] - pop esi - pop eax - cmp dl, 2 - jnz @f - lodsd - push esi - call get_dump - jmp exception.done -@@: test eax, eax - jz .notint1 -; if exception is result of single step, simply ignore it and continue - test dword [esi], 0xF - jnz dbgmsgstart.5 - lodsd - push esi - mov esi, oldcontext - mov edi, context - mov ecx, 28h/4 - rep movsd - call DoResume - jmp dbgmsgend -.notint1: -; in other case, work as without temp_break - lodsd - push esi - push eax - jmp exception.4 -.notour: + push eax + mov eax, [temp_break] + dec eax + push esi + call enable_breakpoint + ; in any case, clear TF and RF + call get_new_context + and [_eflags], not 10100h ; clear TF,RF + call set_context + xor edx, edx + mov [temp_break], edx + xchg dl, [bAfterGo] + pop esi + pop eax + cmp dl, 2 + jnz @f + lodsd + push esi + call get_dump + jmp exception.done + @@: + test eax, eax + jz .notint1 + ; if exception is result of single step, simply ignore it and continue + test dword [esi], 0xF + jnz dbgmsgstart.5 + lodsd + push esi + mov esi, oldcontext + mov edi, context + mov ecx, 28h/4 + rep movsd + call DoResume + jmp dbgmsgend + + .notint1: + ; in other case, work as without temp_break + lodsd + push esi + push eax + jmp exception.4 + + .notour: + +; TODO: split it out debugmsg: - neg [dbgbufsize] - mov esi, dbgbuf + neg [dbgbufsize] + mov esi, dbgbuf + +; TODO: make it local dbgmsgstart: - lodsd -; push eax esi -; push dword [esi] -; mov esi, dbgmsg_str -; call put_message_nodraw -; pop esi eax - add esi, 4 - dec eax - jz exception - dec eax - jz terminated - mov [bSuspended], 1 - cmp [bAfterGo], 0 - jnz after_go_exception - push esi - call get_new_context - and [_eflags], not 10100h ; clear TF,RF - call set_context - pop esi -.5: - push esi - call get_dump - pop esi - lodsd - xor ecx, ecx -.6: - bt eax, ecx - jnc .7 - mov ebx, [drx_break+ecx*4] - test ebx, ebx - jz .7 - pushad - dec ebx - push ebx - mov esi, aBreakStop - call put_message_nodraw - popad -.7: - inc ecx - cmp cl, 4 - jb .6 - push esi - jmp exception.done_draw + lodsd +; push eax esi +; push dword [esi] +; mov esi, dbgmsg_str +; call put_message_nodraw +; pop esi eax + add esi, 4 + dec eax + jz exception + dec eax + jz terminated + mov [bSuspended], 1 + cmp [bAfterGo], 0 + jnz after_go_exception + push esi + call get_new_context + 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 + pop esi + lodsd + xor ecx, ecx + + .6: + bt eax, ecx + jnc .7 + mov ebx, [drx_break+ecx*4] + test ebx, ebx + jz .7 + pushad + dec ebx + push ebx + mov esi, aBreakStop + call put_message_nodraw + popad + + .7: + inc ecx + cmp cl, 4 + jb .6 + push esi + jmp exception.done_draw + +; TODO: make it local terminated: - push esi - mov esi, terminated_msg - call put_message - and [debuggee_pid], 0 - and [temp_break], 0 - mov [bAfterGo], 0 - xor eax, eax - mov ecx, breakpoints_n*6/4+4 - mov edi, breakpoints - rep stosd - cmp [bReload], 1 - sbb [bReload], -1 - jnz exception.done - call free_symbols - jmp exception.done + push esi + mov esi, terminated_msg + call put_message + and [debuggee_pid], 0 + and [temp_break], 0 + mov [bAfterGo], 0 + xor eax, eax + mov ecx, breakpoints_n*6/4+4 + mov edi, breakpoints + rep stosd + cmp [bReload], 1 + sbb [bReload], -1 + jnz exception.done + call free_symbols + jmp exception.done + exception: - mov [bSuspended], 1 - cmp [bAfterGo], 0 - jnz after_go_exception - lodsd - push esi - push eax - call get_new_context - and [_eflags], not 10100h ; clear TF,RF - call set_context -.4: - call get_dump - pop eax -; int3 command generates exception 0D, #GP - push eax - cmp al, 0Dh - jnz .notdbg -; check for 0xCC byte at eip - push 0 - push 69 - 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 - mov eax, [_eip] - call find_enabled_breakpoint - jnz .user_int3 -; dbg breakpoint; clear if one-shot - pop ecx - push eax - mov esi, aBreakStop - test byte [edi+4], 4 - jz .put_msg_eax - pop ecx - call clear_breakpoint - jmp .done -.user_int3: - mov eax, [_eip] - inc [_eip] - pop ecx - push eax - 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 - call redraw_title - call redraw_registers - call redraw_dump - call update_disasm_eip + mov [bSuspended], 1 + cmp [bAfterGo], 0 + jnz after_go_exception + lodsd + push esi + push eax + 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 + ; int3 command generates exception 0D, #GP + push eax + cmp al, 0Dh + jnz .notdbg + ; check for 0xCC byte at eip + push 0 + ;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 + cmp al, 0xCC + jnz .notdbg + ; this is either dbg breakpoint or int3 cmd in debuggee + mov eax, [_eip] + call find_enabled_breakpoint + jnz .user_int3 + ; dbg breakpoint; clear if one-shot + pop ecx + push eax + mov esi, aBreakStop + test byte [edi+4], 4 + jz .put_msg_eax + pop ecx + call clear_breakpoint + jmp .done + + .user_int3: + mov eax, [_eip] + inc [_eip] + pop ecx + push eax + 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 18, 3, [dbgwnd] ; activate dbg window + call redraw_title + call draw_registers.redraw + call draw_dump.redraw + call update_disasm_eip + dbgmsgend: - pop esi - mov ecx, [dbgbuflen] - add ecx, dbgbuf - cmp esi, ecx - jnz dbgmsgstart - and [dbgbuflen], 0 - neg [dbgbufsize] - cmp [bReload], 2 - jnz @f - mov [bReload], 0 - call do_reload -@@: - jmp waitevent + pop esi + mov ecx, [dbgbuflen] + add ecx, dbgbuf + cmp esi, ecx + jnz dbgmsgstart + and [dbgbuflen], 0 + neg [dbgbufsize] + cmp [bReload], 2 + 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 -CtrlF8: - cmp [debuggee_pid], 0 - jz CtrlF7.no - call OnProceed - jmp CtrlF7.no + cmp [debuggee_pid], 0 + jz .no + call OnStep + .no: + jmp waitevent + +; TODO: make it local +CtrlF8: + cmp [debuggee_pid], 0 + jz CtrlF7.no + call OnProceed + jmp CtrlF7.no + +;----------------------------------------------------------------------------- +; Step execution event + +;Here we get [] argument at do step times OnStep: - cmp [bSuspended], 0 - jz .running - call get_context - or byte [_eflags+1], 1 ; set TF - call set_context - and byte [_eflags+1], not 1 -; if instruction at eip is "int xx", set one-shot breakpoint immediately after - mov eax, [_eip] - call find_enabled_breakpoint - 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 - cmp eax, edx - pop eax - jnz .doit - cmp al, 0xCD - jz .int - cmp ax, 0x050F - jz .syscall - cmp ax, 0x340F - jz .sysenter -; resume process -.doit: - call GoOn - cmp [bAfterGo], 0 - jz @f - mov [bAfterGo], 2 -@@: - ret -.sysenter: ; return address is [ebp-4] - push 0 - push 69 - pop eax - inc edx ; read 4 bytes - mov esi, [_ebp] - sub esi, 4 - mcall - cmp eax, edx - pop eax - jnz .syscall - push eax - and byte [_eflags+1], not 1 - 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 - pop eax - jz .doit -; there is no enabled breakpoint yet; set temporary breakpoint - mov bl, 5 - call add_breakpoint - jmp .doit -.running: - mov esi, aRunningErr - jmp put_message + 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 + and byte [_eflags+1], not 1 + ; if instruction at eip is "int xx", set one-shot breakpoint immediately after + mov eax, [_eip] + call find_enabled_breakpoint + 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 69, 6, [debuggee_pid], 3, [_eip], esp + cmp eax, edx + pop eax + jnz .doit + cmp al, 0xCD + jz .int + cmp ax, 0x050F + jz .syscall + cmp ax, 0x340F + jz .sysenter + + ; resume process + .doit: + call GoOn + 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 + + ; return address is [ebp-4] + .sysenter: + push 0 + ;push 69 + ;pop eax + inc edx ; read 4 bytes + mov esi, [_ebp] + sub esi, 4 + mcall 69 + cmp eax, edx + pop eax + jnz .syscall + push eax + and byte [_eflags+1], not 1 + 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 + pop eax + jz .doit + ; there is no enabled breakpoint yet; set temporary breakpoint + 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 - mov esi, [_eip] -@@: - call get_byte_nobreak - jc OnStep - inc esi -; skip prefixes - call is_prefix - jz @b - cmp al, 0xE8 ; call - jnz @f - add esi, 4 - jmp .doit -@@: ; 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 - cmp al, 0xAA - jb @f - cmp al, 0xB0 - jb .doit -@@: ; E0=loopnz,E1=loopz,E2=loop - cmp al, 0xE0 - jb .noloop - cmp al, 0xE2 - ja .noloop - inc esi - jmp .doit -.noloop: ; FF /2 = call - cmp al, 0xFF - jnz OnStep - call get_byte_nobreak - jc OnStep - inc esi - mov cl, al - and al, 00111000b - cmp al, 00010000b - jnz OnStep -; skip instruction - mov al, cl - and eax, 7 - shr cl, 6 - jz .mod0 - jp .doit - 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 - 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 - mov eax, esi - call find_enabled_breakpoint - jz .ret - mov eax, esi - mov bl, 5 - call add_breakpoint - jmp OnStep.doit -.ret: - ret + 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.stepone + inc esi + ; skip prefixes + call is_prefix + jz @b + cmp al, 0xE8 ; call + jnz @f + add esi, 4 + jmp .doit + + ; 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 + @@: + cmp al, 0xAA + jb @f + cmp al, 0xB0 + jb .doit + + ; E0 = loopnz; E1 = loopz; E2 = loop + @@: + cmp al, 0xE0 + jb .noloop + cmp al, 0xE2 + ja .noloop + inc esi + jmp .doit + + ; FF /2 = call + .noloop: + cmp al, 0xFF + jnz OnStep.stepone + call get_byte_nobreak + jc OnStep.stepone + inc esi + mov cl, al + and al, 00111000b + cmp al, 00010000b + jnz OnStep.stepone + ; skip instruction + mov al, cl + and eax, 7 + shr cl, 6 + jz .mod0 + jp .doit + 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.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.stepone + mov eax, esi + call find_enabled_breakpoint + 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 - jnz .nobreak - mov al, [edi+5] - clc - ret -.nobreak: - push 69 - pop eax - push 6 - pop ebx - mov ecx, [debuggee_pid] - xor edx, edx - push edx - inc edx - mov edi, esp - mcall - dec eax - clc - jz @f - stc -@@: pop eax - ret + mov eax, esi + call find_enabled_breakpoint + jnz .nobreak + mov al, [edi+5] + clc + ret + + .nobreak: + ;push 69 + ;pop eax + ;push 6 + ;pop ebx + ;mov ecx, [debuggee_pid] + xor edx, edx + push edx + inc edx + mov edi, esp + 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 +include 'parser.inc' -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 - -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 - -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 +;----------------------------------------------------------------------------- +; Calculate expression event OnCalc: - mov esi, [curarg] - call calc_expression - jc .ret - push ebp - mov esi, calc_string - call put_message_nodraw - jmp draw_messages -.ret: - ret + mov esi, [curarg] + call calc_expression + jc .ret + push ebp + mov esi, calc_string + call put_message_nodraw + jmp draw_messages + + .ret: + ret + +;----------------------------------------------------------------------------- +; Dump memory event OnDump: - mov esi, [curarg] - cmp byte [esi], 0 - 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 -.ret: - ret + mov esi, [curarg] + cmp byte [esi], 0 + jnz .param + add [dumppos], dump_height*10h + jmp .doit + + .param: + call calc_expression + jc .ret + mov [dumppos], ebp + + .doit: + call get_dump + call draw_dump.redraw + + .ret: + ret + +;----------------------------------------------------------------------------- +; Dissassemble block of executable event OnUnassemble: - mov esi, [curarg] - cmp byte [esi], 0 - jnz .param - mov eax, [disasm_start_pos] - mov ecx, disasm_height - mov [disasm_cur_pos], eax -.l: - mov eax, [disasm_cur_pos] - call find_symbol - jc @f - dec ecx - jz .m -@@: - push ecx - call disasm_instr - 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] - mov [disasm_start_pos], eax - call update_disasm - pop [disasm_start_pos] - pop eax - cmp [disasm_cur_str], 0 - jz @f - mov [disasm_start_pos], eax -.ret: - ret -@@: - call update_disasm -.err: - mov esi, aInvAddr - jmp put_message + mov esi, [curarg] + cmp byte [esi], 0 + jnz .param + mov eax, [disasm_start_pos] + mov ecx, disasm_height + mov [disasm_cur_pos], eax + + .l: + mov eax, [disasm_cur_pos] + call find_symbol + jc @f + dec ecx + jz .m + + @@: + push ecx + call disasm_instr + 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] + mov [disasm_start_pos], eax + call update_disasm + pop [disasm_start_pos] + pop eax + 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 find_reg - jnc @f -.err: - mov esi, RSyntax - jmp put_message -@@: - call skip_spaces - test al, al - jz .err - cmp al, '=' - jnz @f - inc esi - call skip_spaces - test al, al - jz .err -@@: - push edi - call calc_expression - pop edi - jc .ret -; now edi=register id, ebp=value - cmp [bSuspended], 0 - mov esi, aRunningErr - jz put_message - xchg eax, ebp - cmp edi, 24 - jz .eip - sub edi, 4 - jb .8lo - sub edi, 4 - jb .8hi - sub edi, 8 - 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 + mov esi, [curarg] + call get_arg.skip_spaces + call find_reg + jnc @f -; Breakpoints manipulation + .err: + mov esi, RSyntax + jmp put_message + + @@: + call get_arg.skip_spaces + test al, al + jz .err + cmp al, '=' + jnz @f + inc esi + call get_arg.skip_spaces + test al, al + jz .err + + @@: + push edi + call calc_expression + pop edi + jc .ret + ; now edi=register id, ebp=value + cmp [bSuspended], 0 + mov esi, aRunningErr + jz put_message + xchg eax, ebp + cmp edi, 24 + jz .eip + sub edi, 4 + jb .8lo + sub edi, 4 + jb .8hi + sub edi, 8 + 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 draw_registers.redraw + +;----------------------------------------------------------------------------- +; Breakpoints manipulation OnBp: - mov esi, [curarg] - call calc_expression - jc .ret - xchg eax, ebp - push eax - call find_breakpoint - inc eax - pop eax - 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 + mov esi, [curarg] + call calc_expression + jc .ret + xchg eax, ebp + push eax + call find_breakpoint + inc eax + pop eax + 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 draw_disasm.redraw OnBpmb: - mov dh, 0011b - jmp DoBpm + mov dh, 0011b + jmp DoBpm + OnBpmw: - mov dh, 0111b - jmp DoBpm + mov dh, 0111b + jmp DoBpm + OnBpmd: - mov dh, 1111b + mov dh, 1111b + DoBpm: - mov esi, [curarg] - cmp byte [esi], 'w' - jnz @f - and dh, not 2 - inc esi -@@: - push edx - call calc_expression - pop edx - jnc @f - ret -@@: -; ebp=expression, dh=flags - movzx eax, dh - shr eax, 2 - test ebp, eax - jz @f - mov esi, aUnaligned - jmp put_message -@@: - mov eax, ebp - mov bl, 0Bh - call add_breakpoint - jnc @f - mov esi, aBreakpointLimitExceeded - jmp put_message -@@: -; now find index - push eax - xor ecx, ecx -.l1: - cmp [drx_break+ecx*4], 0 - jnz .l2 - push 69 - pop eax - push ecx - mov dl, cl - mov ecx, [debuggee_pid] - mov esi, ebp - push 9 - pop ebx - mcall - test eax, eax - jz .ok - pop ecx -.l2: - inc ecx - cmp ecx, 4 - jb .l1 - pop eax - call clear_breakpoint - mov esi, aBreakpointLimitExceeded - jmp put_message -.ok: - pop ecx - pop eax - and byte [edi], not 2 ; breakpoint is enabled - shl dl, 6 - or dl, dh - mov byte [edi+1], dl - inc eax - mov [drx_break+ecx*4], eax - ret + mov esi, [curarg] + cmp byte [esi], 'w' + jnz @f + and dh, not 2 + inc esi + + @@: + push edx + call calc_expression + pop edx + jnc @f + ret + + ; ebp = expression, dh = flags + @@: + movzx eax, dh + shr eax, 2 + test ebp, eax + jz @f + mov esi, aUnaligned + jmp put_message + + @@: + mov eax, ebp + mov bl, 0Bh + call add_breakpoint + jnc @f + mov esi, aBreakpointLimitExceeded + jmp put_message + + ; now find index + @@: + push eax + xor ecx, ecx + + .l1: + cmp [drx_break+ecx*4], 0 + jnz .l2 + ;push 69 + ;pop eax + push ecx + mov dl, cl + ;mov ecx, [debuggee_pid] + mov esi, ebp + ;push 9 + ;pop ebx + mcall 69, 9, [debuggee_pid] + test eax, eax + jz .ok + pop ecx + + .l2: + inc ecx + cmp ecx, 4 + jb .l1 + pop eax + call clear_breakpoint + mov esi, aBreakpointLimitExceeded + jmp put_message + + .ok: + pop ecx + pop eax + and byte [edi], not 2 ; breakpoint is enabled + shl dl, 6 + or dl, dh + mov byte [edi+1], dl + inc eax + mov [drx_break+ecx*4], eax + ret OnBc: - mov esi, [curarg] -@@: call get_hex_number - jc OnBp.ret - call clear_breakpoint - jmp @b + mov esi, [curarg] + + @@: + call get_hex_number + jc OnBp.ret + call clear_breakpoint + jmp @b OnBd: - mov esi, [curarg] -@@: call get_hex_number - jc OnBp.ret - call disable_breakpoint - jmp @b + mov esi, [curarg] + + @@: + call get_hex_number + jc OnBp.ret + call disable_breakpoint + jmp @b OnBe: - mov esi, [curarg] -@@: call get_hex_number - jc OnBp.ret - push eax - call find_enabled_breakpoint - pop eax - jz .err - call enable_breakpoint - jmp @b -.err: - mov esi, OnBeErrMsg - jmp put_message + mov esi, [curarg] + @@: + call get_hex_number + jc OnBp.ret + push eax + call find_enabled_breakpoint + pop eax + 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 - xor ecx, ecx - xor edx, edx -@@: - lodsb - call is_hex_digit - jc .ret - shl edx, 4 - or dl, al - inc ecx - jmp @b -.ret: - dec esi - cmp ecx, 1 - xchg eax, edx - ret + call get_arg.skip_spaces + xor ecx, ecx + xor edx, edx + + @@: + lodsb + call is_hex_digit + jc .ret + shl edx, 4 + or dl, al + inc ecx + jmp @b + + .ret: + dec esi + cmp ecx, 1 + xchg eax, edx + ret + +;----------------------------------------------------------------------------- +; Breakpoints list event OnBl: - mov esi, [curarg] - cmp byte [esi], 0 - jz .listall - call get_hex_number - jc .ret - cmp eax, breakpoints_n - jae .err - push eax - add eax, eax - lea edi, [breakpoints + eax + eax*2] - pop eax - 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 - push edi eax - call show_break_info - pop eax edi -.cont: - add edi, 6 - inc eax - cmp eax, breakpoints_n - jb @b - ret + mov esi, [curarg] + cmp byte [esi], 0 + jz .listall + call get_hex_number + jc .ret + cmp eax, breakpoints_n + jae .err + push eax + add eax, eax + lea edi, [breakpoints + eax + eax*2] + pop eax + 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 + push edi eax + call show_break_info + pop eax edi + + .cont: + add edi, 6 + inc eax + cmp eax, breakpoints_n + jb @b + ret + +;----------------------------------------------------------------------------- + show_break_info: - push edi - test byte [edi+4], 8 - jnz .dr - push dword [edi] - push eax - mov esi, aBreakNum - call put_message_nodraw - jmp .cmn -.dr: - push eax - mov esi, aMemBreak1 - call put_message_nodraw - pop edi - push edi - mov esi, aMemBreak2 - test byte [edi+5], 2 - jz @f - mov esi, aMemBreak3 -@@: - call put_message_nodraw - pop edi - push edi - mov esi, aMemBreak6 - test byte [edi+5], 8 - jnz @f - mov esi, aMemBreak5 - test byte [edi+5], 4 - jnz @f - mov esi, aMemBreak4 -@@: - call put_message_nodraw - pop edi - push edi - push dword [edi] - mov esi, aMemBreak7 - call put_message_nodraw -.cmn: - pop edi - test byte [edi+4], 2 - jz @f - push edi - 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 + push edi + test byte [edi+4], 8 + jnz .dr + push dword [edi] + push eax + mov esi, aBreakNum + call put_message_nodraw + jmp .cmn + + .dr: + push eax + mov esi, aMemBreak1 + call put_message_nodraw + pop edi + push edi + mov esi, aMemBreak2 + test byte [edi+5], 2 + jz @f + mov esi, aMemBreak3 + + @@: + call put_message_nodraw + pop edi + push edi + mov esi, aMemBreak6 + test byte [edi+5], 8 + jnz @f + mov esi, aMemBreak5 + test byte [edi+5], 4 + jnz @f + mov esi, aMemBreak4 + + @@: + call put_message_nodraw + pop edi + push edi + push dword [edi] + mov esi, aMemBreak7 + call put_message_nodraw + + .cmn: + pop edi + test byte [edi+4], 2 + jz @f + push edi + 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 - add edi, 6 - inc ecx - cmp ecx, breakpoints_n - jb @b - stc - ret -.found: - stosd - xchg eax, ecx - mov [edi], bl - test bl, 2 - jnz @f - or byte [edi], 2 - push eax - call enable_breakpoint - pop eax -@@: - clc - ret + xor ecx, ecx + mov edi, breakpoints + + @@: + test byte [edi+4], 1 + jz .found + add edi, 6 + inc ecx + cmp ecx, breakpoints_n + jb @b + stc + ret + + .found: + stosd + xchg eax, ecx + mov [edi], bl + test bl, 2 + jnz @f + or byte [edi], 2 + 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 - dec eax - push eax - add eax, eax - lea edi, [breakpoints + eax + eax*2 + 4] - test byte [edi], 1 - pop eax - jz .ret - push edi - call disable_breakpoint - pop edi - mov byte [edi], 0 -.ret: - ret + 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 + dec eax + push eax + add eax, eax + lea edi, [breakpoints + eax + eax*2 + 4] + test byte [edi], 1 + pop eax + jz .ret + push edi + call disable_breakpoint + pop edi + mov byte [edi], 0 + + .ret: + ret + +;----------------------------------------------------------------------------- +; Disable breakpoint disable_breakpoint: - cmp eax, breakpoints_n - jae .ret - add eax, eax - lea edi, [breakpoints + eax + eax*2 + 5] - test byte [edi-1], 1 - jz .ret - test byte [edi-1], 2 - jnz .ret - or byte [edi-1], 2 - 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 - 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 - ret + cmp eax, breakpoints_n + jae .ret + add eax, eax + lea edi, [breakpoints + eax + eax*2 + 5] + test byte [edi-1], 1 + jz .ret + test byte [edi-1], 2 + jnz .ret + or byte [edi-1], 2 + 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 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 69, 9, [debuggee_pid] + ret + +;----------------------------------------------------------------------------- +; Enable breakpoint enable_breakpoint: - push esi - cmp eax, breakpoints_n - jae .ret - add eax, eax - lea edi, [breakpoints + eax + eax*2 + 5] - test byte [edi-1], 1 - jz .ret - test byte [edi-1], 2 - jz .ret - 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 - dec eax - jnz .err - mov al, 69 - push 0xCC - mov edi, esp - inc ebx - mcall - pop eax -.ret: - pop esi - ret -.err: - or byte [edi-1], 2 - mov esi, aBreakErr - call put_message - pop esi - ret -.dr: - push 9 - pop ebx - push 69 - pop eax - mov esi, [edi-5] - mov ecx, [debuggee_pid] - mov dl, [edi] - shr dl, 6 - mov dh, [edi] - and dh, 0xF - mcall - test eax, eax - jnz .err - pop esi - ret + push esi + cmp eax, breakpoints_n + jae .ret + add eax, eax + lea edi, [breakpoints + eax + eax*2 + 5] + test byte [edi-1], 1 + jz .ret + test byte [edi-1], 2 + jz .ret + 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 69, 6, [debuggee_pid], 1, [edi-5] + dec eax + jnz .err + ;mov al, 69 + push 0xCC + mov edi, esp + inc ebx + mcall 69 + pop eax + + .ret: + pop esi + ret + + .err: + or byte [edi-1], 2 + mov esi, aBreakErr + call put_message + pop esi + ret + + .dr: + ;push 9 + ;pop ebx + ;push 69 + ;pop eax + mov esi, [edi-5] + ;mov ecx, [debuggee_pid] + mov dl, [edi] + shr dl, 6 + mov dh, [edi] + and dh, 0xF + 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 - test byte [edi+4], 8 - jnz .cont - cmp [edi], ecx - jz .found -.cont: - add edi, 6 - inc eax - cmp eax, breakpoints_n - jb @b - or eax, -1 -.found: - ret + xor ecx, ecx + xchg eax, ecx + mov edi, breakpoints + + @@: + test byte [edi+4], 1 + jz .cont + test byte [edi+4], 8 + jnz .cont + cmp [edi], ecx + jz .found + + .cont: + add edi, 6 + inc eax + 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 - test byte [edi+4], 2 or 8 - jnz .cont - cmp [edi], ecx - jz .found -.cont: - add edi, 6 - inc eax - cmp eax, breakpoints_n - jb @b - or eax, -1 -.found: - ret + xor ecx, ecx + xchg eax, ecx + mov edi, breakpoints + + @@: + test byte [edi+4], 1 + jz .cont + test byte [edi+4], 2 or 8 + jnz .cont + cmp [edi], ecx + jz .found + + .cont: + add edi, 6 + inc eax + 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 - mov esi, aRunningErr - cmp [bSuspended], 0 - jz put_message -; all breakpoints must be disabled - mov edi, breakpoints -@@: - test byte [edi+4], 1 - jz .cont - test byte [edi+4], 2 - jnz .cont - mov esi, aEnabledBreakErr - jmp put_message -.cont: - add edi, 6 - cmp edi, breakpoints+breakpoints_n*6 - jb @b -; ok, now do it -; set breakpoint on 0xC dword access - push 9 - pop ebx - mov ecx, [debuggee_pid] - mov dx, 1111b*256 - push 0xC - pop esi -@@: - push 69 - pop eax - mcall - 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 - dec eax - jz .redraw - dec eax - jz .key - dec eax - jnz .debug -; 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 - cmp esi, aUnpacked - jnz OnSuspend - jmp AfterSuspend -.debug: - cmp [dbgbuflen], 4*3 - jnz .notour - cmp dword [dbgbuf], 3 - jnz .notour - test byte [dbgbuf+8], 1 - jnz .our -.notour: - mov esi, aInterrupted - push edx - call put_message - pop edx - or dh, 80h - push 69 - pop eax - push 9 - pop ebx - mov ecx, [debuggee_pid] - mcall - 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 - pop eax - pop edx - cmp eax, [_eip] - jz .done - call DoResume - jmp .wait -.done: - mov esi, aUnpacked - jmp .x1 + ; program must be loaded - checked when command was parsed + ; program must be stopped + mov esi, aRunningErr + cmp [bSuspended], 0 + jz put_message + ; all breakpoints must be disabled + mov edi, breakpoints + + @@: + test byte [edi+4], 1 + jz .cont + test byte [edi+4], 2 + jnz .cont + mov esi, aEnabledBreakErr + jmp put_message + + .cont: + add edi, 6 + cmp edi, breakpoints+breakpoints_n*6 + jb @b + ; ok, now do it + ; set breakpoint on 0xC dword access + push 9 + pop ebx + mov ecx, [debuggee_pid] + mov dx, 1111b*256 + push 0xC + pop esi + + @@: + ;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 10 + dec eax + jz .redraw + dec eax + jz .key + dec eax + jnz .debug + ; 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 69, 9, [debuggee_pid] + cmp esi, aUnpacked + jnz OnSuspend + jmp AfterSuspend + + .debug: + cmp [dbgbuflen], 4*3 + jnz .notour + cmp dword [dbgbuf], 3 + jnz .notour + test byte [dbgbuf+8], 1 + jnz .our + + .notour: + mov esi, aInterrupted + push edx + call put_message + pop edx + or dh, 80h + ;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 69, 6, [debuggee_pid], 4, 0xC, esp + pop eax + pop edx + cmp eax, [_eip] + 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 + cmpsd + jnz @f + cmp esi, edi + + @@: + ret + +; purpose of this function? compare2: - cmpsd -@@: - cmpsb - jnz @f - cmp byte [esi-1], 0 - jnz @b - cmp esi, edi -@@: - ret + cmpsd + + @@: + cmpsb + jnz @f + cmp byte [esi-1], 0 + jnz @b + cmp esi, edi + + @@: + ret free_symbols: - mov ecx, [symbols] - jecxz @f - mcall 68, 13 - and [symbols], 0 - and [num_symbols], 0 -@@: - ret + mov ecx, [symbols] + jecxz @f + mcall 68, 13 + and [symbols], 0 + and [num_symbols], 0 + + @@: + ret +;----------------------------------------------------------------------------- +; Load symbols event OnLoadSymbols.fileerr: - test ebp, ebp - jz @f - mcall 68, 13, edi - ret -@@: - push eax - mcall 68, 13, edi - mov esi, aCannotLoadFile - call put_message_nodraw - pop eax - cmp eax, 0x20 - jae .unk - mov esi, [load_err_msgs + eax*4] - test esi, esi - jnz put_message -.unk: - mov esi, unk_err_msg2 - jmp put_message + test ebp, ebp + jz @f + mcall 68, 13, edi + ret + + @@: + push eax + mcall 68, 13, edi + mov esi, aCannotLoadFile + call put_message_nodraw + pop eax + cmp eax, 0x20 + jae .unk + mov esi, [load_err_msgs + eax*4] + test esi, esi + jnz put_message + + .unk: + mov esi, unk_err_msg2 + jmp put_message OnLoadSymbols: - xor ebp, ebp -; load input file - mov esi, [curarg] - call free_symbols -.silent: - xor edi, edi - cmp [num_symbols], edi - jz @f - ret -@@: - mov ebx, fn70_attr_block - mov [ebx+21], esi - mcall 70 - test eax, eax - jnz .fileerr - cmp dword [fileattr+36], edi - jnz .memerr - mov ecx, dword [fileattr+32] - mcall 68, 12 - test eax, eax - jz .memerr - mov edi, eax - mov ebx, fn70_read_block - mov [ebx+12], ecx - mov [ebx+16], edi - mov [ebx+21], esi - mcall 70 - test eax, eax - jnz .fileerr -; calculate memory requirements - lea edx, [ecx+edi-1] ; edx = EOF-1 - mov esi, edi - xor ecx, ecx -.calcloop: - cmp esi, edx - jae .calcdone - cmp word [esi], '0x' - jnz .skipline - inc esi - inc esi -@@: - cmp esi, edx - jae .calcdone - lodsb - or al, 20h - sub al, '0' - cmp al, 9 - jbe @b - sub al, 'a'-'0'-10 - cmp al, 15 - jbe @b - dec esi -@@: - cmp esi, edx - ja .calcdone - lodsb - cmp al, 20h - jz @b - jb .calcloop - cmp al, 9 - jz @b - add ecx, 12+1 - inc [num_symbols] -@@: - inc ecx - cmp esi, edx - ja .calcdone - lodsb - cmp al, 0xD - jz .calcloop - cmp al, 0xA - jz .calcloop - jmp @b -.skipline: - cmp esi, edx - jae .calcdone - lodsb - cmp al, 0xD - jz .calcloop - cmp al, 0xA - jz .calcloop - jmp .skipline -.calcdone: - mcall 68, 12 - test eax, eax - jnz .memok - inc ebx - mov ecx, edi - mov al, 68 - mcall -.memerr: - mov esi, aNoMemory - jmp put_message -.memok: - mov [symbols], eax - mov ebx, eax - push edi - mov esi, edi - 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 -.readloop: - cmp esi, edx - jae .readdone - cmp word [esi], '0x' - jnz .readline - inc esi - inc esi - xor eax, eax - xor ecx, ecx -@@: - shl ecx, 4 - add ecx, eax - cmp esi, edx - jae .readdone - lodsb - or al, 20h - sub al, '0' - cmp al, 9 - jbe @b - sub al, 'a'-'0'-10 - cmp al, 15 - jbe @b - dec esi -@@: - cmp esi, edx - ja .readdone - lodsb - cmp al, 20h - jz @b - jb .readloop - cmp al, 9 - jz @b - mov dword [ebx], edi - add ebx, 4 - mov dword [ebp], edi - add ebp, 4 - mov dword [edi], ecx - add edi, 4 - stosb -@@: - xor eax, eax - stosb - cmp esi, edx - ja .readdone - lodsb - cmp al, 0xD - jz .readloop - cmp al, 0xA - jz .readloop - mov byte [edi-1], al - jmp @b -.readline: - cmp esi, edx - jae .readdone - lodsb - cmp al, 0xD - jz .readloop - cmp al, 0xA - jz .readloop - jmp .readline -.readdone: - pop ecx - mcall 68, 13 - mov ecx, [num_symbols] - mov edx, [symbols] - mov ebx, compare - call sort - mov ecx, [num_symbols] - lea edx, [edx+ecx*4] - mov ebx, compare2 - call sort - mov esi, aSymbolsLoaded - call put_message - jmp redraw_disasm + xor ebp, ebp + ; load input file + mov esi, [curarg] + call free_symbols + + .silent: + xor edi, edi + cmp [num_symbols], edi + jz @f + + call free_symbols + ;ret + + @@: + mov ebx, fn70_attr_block + mov [ebx+21], esi + mcall 70 + test eax, eax + jnz .fileerr + cmp dword [fileattr+36], edi + jnz .memerr + mov ecx, dword [fileattr+32] + mcall 68, 12 + test eax, eax + jz .memerr + mov edi, eax + mov ebx, fn70_read_block + mov [ebx+12], ecx + mov [ebx+16], edi + mov [ebx+21], esi + mcall 70 + test eax, eax + jnz .fileerr + ; calculate memory requirements + lea edx, [ecx+edi-1] ; edx = EOF-1 + mov esi, edi + xor ecx, ecx + + .calcloop: + cmp esi, edx + jae .calcdone + cmp word [esi], '0x' + jnz .skipline + inc esi + inc esi + + @@: + cmp esi, edx + jae .calcdone + lodsb + or al, 20h + sub al, '0' + cmp al, 9 + jbe @b + sub al, 'a'-'0'-10 + cmp al, 15 + jbe @b + dec esi + + @@: + cmp esi, edx + ja .calcdone + lodsb + cmp al, 20h + jz @b + jb .calcloop + cmp al, 9 + jz @b + add ecx, 12+1 + inc [num_symbols] + + @@: + inc ecx + cmp esi, edx + ja .calcdone + lodsb + cmp al, 0xD + jz .calcloop + cmp al, 0xA + jz .calcloop + jmp @b + + .skipline: + cmp esi, edx + jae .calcdone + lodsb + cmp al, 0xD + jz .calcloop + cmp al, 0xA + jz .calcloop + jmp .skipline + + .calcdone: + mcall 68, 12 + test eax, eax + jnz .memok + inc ebx + mov ecx, edi + mov al, 68 + mcall + + .memerr: + mov esi, aNoMemory + jmp put_message + + .memok: + mov [symbols], eax + mov ebx, eax + push edi + mov esi, edi + 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 + .readloop: + cmp esi, edx + jae .readdone + cmp word [esi], '0x' + jnz .readline + inc esi + inc esi + xor eax, eax + xor ecx, ecx + + @@: + shl ecx, 4 + add ecx, eax + cmp esi, edx + jae .readdone + lodsb + or al, 20h + sub al, '0' + cmp al, 9 + jbe @b + sub al, 'a'-'0'-10 + cmp al, 15 + jbe @b + dec esi + + @@: + cmp esi, edx + ja .readdone + lodsb + cmp al, 20h + jz @b + jb .readloop + cmp al, 9 + jz @b + mov dword [ebx], edi + add ebx, 4 + mov dword [ebp], edi + add ebp, 4 + mov dword [edi], ecx + add edi, 4 + stosb + + @@: + xor eax, eax + stosb + cmp esi, edx + ja .readdone + lodsb + cmp al, 0xD + jz .readloop + cmp al, 0xA + jz .readloop + mov byte [edi-1], al + jmp @b + + .readline: + cmp esi, edx + jae .readdone + lodsb + cmp al, 0xD + jz .readloop + cmp al, 0xA + jz .readloop + jmp .readline + + .readdone: + pop ecx + mcall 68, 13 + mov ecx, [num_symbols] + mov edx, [symbols] + mov ebx, compare + call sort + mov ecx, [num_symbols] + lea edx, [edx+ecx*4] + mov ebx, compare2 + call sort + mov esi, aSymbolsLoaded + call put_message + 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 - mov esi, [symbols] - mov ecx, [num_symbols] - mov ebx, [esi] - cmp [ebx], eax - jz .donez - jb @f - pop edx ecx ebx - jmp .ret0 -@@: -; invariant: symbols_addr[edx] < eax < symbols_addr[ecx] -.0: - push edx -.1: - add edx, ecx - sar edx, 1 - cmp edx, [esp] - jz .done2 - mov ebx, [esi+edx*4] - cmp [ebx], eax - jz .done - ja .2 - mov [esp], edx - jmp .1 -.2: - mov ecx, edx - pop edx - jmp .0 -.donecont: - dec edx -.done: - test edx, edx - jz @f - mov ebx, [esi+edx*4-4] - cmp [ebx], eax - jz .donecont -@@: - pop ecx -.donez: - mov esi, [esi+edx*4] - add esi, 4 - pop edx ecx ebx - clc - ret -.done2: - lea esi, [esi+edx*4] - pop ecx edx ecx ebx - stc - ret + cmp [num_symbols], 0 + jnz @f -find_symbol_name: + .ret0: + xor esi, esi + stc + ret + + @@: + push ebx ecx edx + xor edx, edx + mov esi, [symbols] + mov ecx, [num_symbols] + mov ebx, [esi] + cmp [ebx], eax + jz .donez + 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 + cmp edx, [esp] + jz .done2 + mov ebx, [esi+edx*4] + cmp [ebx], eax + jz .done + ja .2 + mov [esp], edx + jmp .1 + + .2: + mov ecx, edx + pop edx + jmp .0 + + .donecont: + dec edx + + .done: + test edx, edx + jz @f + mov ebx, [esi+edx*4-4] + cmp [ebx], eax + jz .donecont + + @@: + pop ecx + + .donez: + mov esi, [esi+edx*4] + add esi, 4 + pop edx ecx ebx + clc + ret + + .done2: + lea esi, [esi+edx*4] + pop ecx edx ecx ebx + stc + ret + +;----------------------------------------------------------------------------- +; ; 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 - pop edx - 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 - cmp edx, [esp] - jz .done2 - call .cmp - jz .done - 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] - pop edi edx ecx ebx - clc - ret -.done2: - pop edx edi edx ecx ebx - stc - ret - -.cmp: - 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 - -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 - -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 +; out: if found: CF = 0, EAX = value +; otherwise CF = 1 +find_symbol_name: + cmp [num_symbols], 0 + jnz @f + + .stc_ret: + stc + ret + + @@: + push ebx ecx edx edi + push -1 + pop edx + 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 + cmp edx, [esp] + jz .done2 + call .cmp + jz .done + 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] + pop edi edx ecx ebx + clc + ret + + .done2: + pop edx edi edx ecx ebx + stc + ret + + .cmp: + mov edi, [ebx+edx*4] + push esi + add edi, 4 + + @@: + cmpsb + jnz @f + cmp byte [esi-1], 0 + jnz @b + + @@: + pop esi + ret + +;----------------------------------------------------------------------------- +; Include disassembler engine + +include 'disasm.inc' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; DATA ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; @@ -5689,482 +2354,533 @@ cgrp15: 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 -prompt db '> ',0 + +begin_str db 'Kolibri Debugger, version 0.32',10 + db 'Hint: type "help" for help, "quit" for quit' +newline db 10,0 +prompt db '> ',0 help_groups: - dd aControl, 0, 0, help_control_msg - db 0 - dd aData, 0, 0, help_data_msg - db 0 - dd aBreakpoints, 0, 0, help_breaks_msg - db 0 + dd aControl, 0, 0, help_control_msg + db 0 + dd aData, 0, 0, help_data_msg + 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 ; &4: command may be called without loaded program ; &8: command may be called with loaded program commands: - dd _aH, OnHelp, HelpSyntax, HelpHelp - db 0Fh - dd aHelp, OnHelp, HelpSyntax, HelpHelp - db 0Fh - dd aQuit, OnQuit, QuitSyntax, QuitHelp - db 0Dh - dd aLoad, OnLoad, LoadSyntax, LoadHelp - db 6 - dd aReload, OnReload, ReloadSyntax, ReloadHelp - db 0Dh - dd aTerminate, OnTerminate, TerminateSyntax, TerminateHelp - db 9 - dd aDetach, OnDetach, DetachSyntax, DetachHelp - db 9 - dd aSuspend, OnSuspend, SuspendSyntax, SuspendHelp - db 9 - dd aResume, OnResume, ResumeSyntax, ResumeHelp - db 0Bh - dd aStep, OnStep, StepSyntax, StepHelp - db 9 - dd aProceed, OnProceed, ProceedSyntax, ProceedHelp - db 9 - dd aCalc, OnCalc, CalcSyntax, CalcHelp - db 0Eh - dd aDump, OnDump, DumpSyntax, DumpHelp - db 0Bh - dd aUnassemble, OnUnassemble, UnassembleSyntax, UnassembleHelp - db 0Bh - dd aBp, OnBp, BpSyntax, BpHelp - db 0Ah - dd aBpm, OnBpmb, BpmSyntax, BpmHelp - db 0Ah - dd aBpmb, OnBpmb, BpmSyntax, BpmHelp - db 0Ah - dd aBpmw, OnBpmw, BpmSyntax, BpmHelp - db 0Ah - dd aBpmd, OnBpmd, BpmSyntax, BpmHelp - db 0Ah - dd aBl, OnBl, BlSyntax, BlHelp - db 0Bh - dd aBc, OnBc, BcSyntax, BcHelp - db 0Ah - dd aBd, OnBd, BdSyntax, BdHelp - db 0Ah - dd aBe, OnBe, BeSyntax, BeHelp - db 0Ah - dd aReg, OnReg, RSyntax, RHelp - db 0Ah - dd aUnpack, OnUnpack, UnpackSyntax, UnpackHelp - db 9 - dd aLoadSymbols, OnLoadSymbols, LoadSymbolsSyntax, LoadSymbolsHelp - db 0Ah - dd 0 -aHelp db 5,'help',0 -_aH db 2,'h',0 -HelpHelp db 'Help on specified function',10 -HelpSyntax db 'Usage: h or help [group | command]',10,0 + dd _aH, OnHelp, HelpSyntax, HelpHelp + db 0Fh + dd aHelp, OnHelp, HelpSyntax, HelpHelp + db 0Fh + dd aQuit, OnQuit, QuitSyntax, QuitHelp + db 0Dh + dd aLoad, OnLoad, LoadSyntax, LoadHelp + db 6 + dd aReload, OnReload, ReloadSyntax, ReloadHelp + db 0Dh + dd aTerminate, OnTerminate, TerminateSyntax, TerminateHelp + db 9 + dd aDetach, OnDetach, DetachSyntax, DetachHelp + db 9 + dd aSuspend, OnSuspend, SuspendSyntax, SuspendHelp + db 9 + dd aResume, OnResume, ResumeSyntax, ResumeHelp + db 0Bh + dd aStep, OnStep, StepSyntax, StepHelp + db 0Bh + dd aProceed, OnProceed, ProceedSyntax, ProceedHelp + db 0Bh + dd aCalc, OnCalc, CalcSyntax, CalcHelp + db 0Eh + dd aDump, OnDump, DumpSyntax, DumpHelp + db 0Bh + dd aUnassemble, OnUnassemble, UnassembleSyntax, UnassembleHelp + db 0Bh + dd aBp, OnBp, BpSyntax, BpHelp + db 0Ah + dd aBpm, OnBpmb, BpmSyntax, BpmHelp + db 0Ah + dd aBpmb, OnBpmb, BpmSyntax, BpmHelp + db 0Ah + dd aBpmw, OnBpmw, BpmSyntax, BpmHelp + db 0Ah + dd aBpmd, OnBpmd, BpmSyntax, BpmHelp + db 0Ah + dd aBl, OnBl, BlSyntax, BlHelp + db 0Bh + dd aBc, OnBc, BcSyntax, BcHelp + db 0Ah + dd aBd, OnBd, BdSyntax, BdHelp + db 0Ah + dd aBe, OnBe, BeSyntax, BeHelp + db 0Ah + dd aReg, OnReg, RSyntax, RHelp + db 0Ah + dd aUnpack, OnUnpack, UnpackSyntax, UnpackHelp + db 9 + 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 +HelpSyntax db 'Usage: h or help [group | command]',10,0 + +help_msg db 'List of known command groups:',10 + 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 + db 'quit - exit from debugger',10 + db 'load [params] - load program for debugging',10 + db 'reload - reload debugging program',10 + db 'load-symbols - load information on symbols for program',10 + db 'terminate - terminate loaded program',10 + db 'detach - detach from debugging program',10 + db 'stop - suspend execution of debugging program',10 + db 'g [] - go on (resume execution of debugging program)',10 + db 's [] - program step, also ',10 + db 'p [] - program wide step, also ',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 '? - calculate value of expression',10 + db 'd [] - dump data at given address',10 + db 'u [] - unassemble instructions at given address',10 + db 'r or',10 + db 'r = - set register value',10,0 + +; Breakpoints commands group -help_msg db 'List of known command groups:',10 - 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 -aControl db 8,'control',0 -help_control_msg db 'List of control commands:',10 - db 'h = help - help',10 - db 'quit - exit from debugger',10 - db 'load [params] - load program for debugging',10 - db 'reload - reload debugging program',10 - db 'load-symbols - load information on symbols for program',10 - db 'terminate - terminate loaded program',10 - db 'detach - detach from debugging program',10 - db 'stop - suspend execution of debugging program',10 - db 'g [] - go on (resume execution of debugging program)',10 - db 's = - program step',10 - db 'p = - program wide step',10 - db 'unpack - try to bypass unpacker code (heuristic)',10,0 -aData db 5,'data',0 -help_data_msg db 'List of data commands:',10 - db '? - calculate value of expression',10 - db 'd [] - dump data at given address',10 - db 'u [] - unassemble instructions at given address',10 - db 'r or',10 - db 'r = - set register value',10,0 aBreakpoints db 12,'breakpoints',0 -help_breaks_msg db 'List of breakpoints commands:',10 - db 'bp - set breakpoint on execution',10 - db 'bpm[b|w|d] - set breakpoint on memory access',10 - db 'bl [] - breakpoint(s) info',10 - db 'bc ... - clear breakpoint',10 - db 'bd ... - disable breakpoint',10 - db 'be ... - enable breakpoint',10,0 +help_breaks_msg db 'List of breakpoints commands:',10 + db 'bp - set breakpoint on execution',10 + db 'bpm[b|w|d] - set breakpoint on memory access',10 + db 'bl [] - breakpoint(s) info',10 + db 'bc ... - clear breakpoint',10 + db 'bd ... - disable breakpoint',10 + db 'be ... - enable breakpoint',10,0 -aQuit db 5,'quit',0 -QuitHelp db 'Quit from debugger',10 -QuitSyntax db 'Usage: quit',10,0 +;----------------------------------------------------------------------------- +; Individual command help messages -aLoad db 5,'load',0 -LoadHelp db 'Load program for debugging',10 -LoadSyntax db 'Usage: load [parameters]',10,0 +aQuit db 5,'quit',0 +QuitHelp db 'Quit from debugger',10 +QuitSyntax db 'Usage: quit',10,0 -aReload db 7,'reload',0 -ReloadHelp db 'Reload debugging program (restart debug session)',10 -ReloadSyntax db 'Usage: reload',10,0 +aLoad db 5,'load',0 +LoadHelp db 'Load program for debugging',10 +LoadSyntax db 'Usage: load [parameters]',10,0 -aTerminate db 10,'terminate',0 +aReload db 7,'reload',0 +ReloadHelp db 'Reload debugging program (restart debug session)',10 +ReloadSyntax db 'Usage: reload',10,0 + +aTerminate db 10,'terminate',0 TerminateHelp db 'Terminate debugged program',10 TerminateSyntax db 'Usage: terminate',10,0 -aDetach db 7,'detach',0 -DetachHelp db 'Detach from debugged program',10 -DetachSyntax db 'Usage: detach',10,0 +aDetach db 7,'detach',0 +DetachHelp db 'Detach from debugged program',10 +DetachSyntax db 'Usage: detach',10,0 -aSuspend db 5,'stop',0 -SuspendHelp db 'Suspend execution of debugged program',10 +aSuspend db 5,'stop',0 +SuspendHelp db 'Suspend execution of debugged program',10 SuspendSyntax db 'Usage: stop',10,0 -aResume db 2,'g',0 -ResumeHelp db 'Go (resume execution of debugged program)',10 -ResumeSyntax db 'Usage: g',10 - db ' or: g - wait until specified address is reached',10,0 +aResume db 2,'g',0 +ResumeHelp db 'Go (resume execution of debugged program)',10 +ResumeSyntax db 'Usage: g',10 + db ' or: g - wait until specified address is reached',10,0 -aStep db 2,'s',0 -StepHelp db 'Make step in debugged program',10 -StepSyntax db 'Usage: s',10,0 +aStep db 2,'s',0 +StepHelp db 'Make step in debugged program',10 +StepSyntax db 'Usage: s []',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 +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 -aDump db 2,'d',0 -DumpHelp db 'Dump data of debugged program',10 -DumpSyntax db 'Usage: d - dump data at specified address',10 - db ' or: d - continue current dump',10,0 +aDump db 2,'d',0 +DumpHelp db 'Dump data of debugged program',10 +DumpSyntax db 'Usage: d - dump data at specified address',10 + db ' or: d - continue current dump',10,0 -aCalc db 2,'?',0 -CalcHelp db 'Calculate value of expression',10 -CalcSyntax db 'Usage: ? ',10,0 +aCalc db 2,'?',0 +CalcHelp db 'Calculate value of expression',10 +CalcSyntax db 'Usage: ? ',10,0 -aUnassemble db 2,'u',0 +aUnassemble db 2,'u',0 UnassembleHelp db 'Unassemble',10 -UnassembleSyntax: - db 'Usage: u - unassemble instructions at specified address',10 - db ' or: u - continue current unassemble screen',10,0 +UnassembleSyntax db 'Usage: u - 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 ',10 - db ' or: r = - set value of to ',10,0 +aReg db 2,'r',0 +RHelp db 'Set register value',10 +RSyntax db 'Usage: r ',10 + db ' or: r = - set value of to ',10,0 -aBp db 3,'bp',0 -BpHelp db 'set BreakPoint on execution',10 -BpSyntax db 'Usage: bp ',10,0 +aBp db 3,'bp',0 +BpHelp db 'set BreakPoint on execution',10 +BpSyntax db 'Usage: bp ',10,0 -aBpm db 4,'bpm',0 -aBpmb db 5,'bpmb',0 -aBpmw db 5,'bpmw',0 -aBpmd db 5,'bpmd',0 -BpmHelp db 'set BreakPoint on Memory access',10 - db 'Maximum 4 breakpoints of this type are allowed',10 - db 'Note that for this breaks debugger is activated after access',10 -BpmSyntax db 'Usage: bpmb [w] ',10 - db ' bpmw [w] ',10 - db ' bpmd [w] ',10 - db ' bpm is synonym for bpmd',10 - db '"w" means break only on writes (default is on read/write)',10,0 +aBpm db 4,'bpm',0 +aBpmb db 5,'bpmb',0 +aBpmw db 5,'bpmw',0 +aBpmd db 5,'bpmd',0 +BpmHelp db 'set BreakPoint on Memory access',10 + db 'Maximum 4 breakpoints of this type are allowed',10 + db 'Note that for this breaks debugger is activated after access',10 +BpmSyntax db 'Usage: bpmb [w] ',10 + db ' bpmw [w] ',10 + db ' bpmd [w] ',10 + db ' bpm is synonym for bpmd',10 + db '"w" means break only on writes (default is on read/write)',10,0 -aBl db 3,'bl',0 -BlHelp db 'Breakpoint List',10 -BlSyntax db 'Usage: bl - list all breakpoints',10 - db ' bl - display info on particular breakpoint',10,0 +aBl db 3,'bl',0 +BlHelp db 'Breakpoint List',10 +BlSyntax db 'Usage: bl - list all breakpoints',10 + db ' bl - display info on particular breakpoint',10,0 -aBc db 3,'bc',0 -BcHelp db 'Breakpoint Clear',10 -BcSyntax db 'Usage: bc ',10 - db 'Examples: bc 2',10 - db ' bc 1 3 4 A',10,0 +aBc db 3,'bc',0 +BcHelp db 'Breakpoint Clear',10 +BcSyntax db 'Usage: bc ',10 + db 'Examples: bc 2',10 + db ' bc 1 3 4 A',10,0 -aBd db 3,'bd',0 -BdHelp db 'Breakpoint Disable',10 -BdSyntax db 'Usage: bd ',10 - db 'Examples: bd 2',10 - db ' bd 1 3 4 A',10,0 +aBd db 3,'bd',0 +BdHelp db 'Breakpoint Disable',10 +BdSyntax db 'Usage: bd ',10 + db 'Examples: bd 2',10 + db ' bd 1 3 4 A',10,0 -aBe db 3,'be',0 -BeHelp db 'Breakpoint Enable',10 -BeSyntax db 'Usage: be ',10 - db 'Examples: be 2',10 - db ' be 1 3 4 A',10,0 +aBe db 3,'be',0 +BeHelp db 'Breakpoint Enable',10 +BeSyntax db 'Usage: be ',10 + db 'Examples: be 2',10 + db ' be 1 3 4 A',10,0 -aUnpack db 7,'unpack',0 -UnpackHelp db 'Try to bypass unpacker code',10 -UnpackSyntax db 'Usage: unpack',10,0 +aUnpack db 7,'unpack',0 +UnpackHelp db 'Try to bypass unpacker code',10 +UnpackSyntax db 'Usage: unpack',10,0 -aLoadSymbols db 13,'load-symbols',0 +aLoadSymbols db 13,'load-symbols',0 LoadSymbolsHelp db 'Load symbolic information for executable',10 LoadSymbolsSyntax db 'Usage: load-symbols ',10,0 aUnknownCommand db 'Unknown command',10,0 -load_err_msg db 'Cannot load program. ',0 -unk_err_msg db 'Unknown error code -%4X',10,0 -aCannotLoadFile db 'Cannot load file. ',0 -unk_err_msg2 db 'Unknown error code %4X.',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 +unk_err_msg2 db 'Unknown error code %4X.',10,0 load_err_msgs: - dd .1, 0, .3, 0, .5, .6, 0, 0, .9, .A, 0, 0, 0, 0, 0, 0 - dd 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, .1E, .1F, .20 -.1 db 'HD undefined.',10,0 -.3 db 'Unknown FS.',10,0 -.5 db 'File not found.',10,0 -.6 db 'Unexpected EOF.',10,0 -.9 db 'FAT table corrupted.',10,0 -.A db 'Access denied.',10,0 -.1E db 'No memory.',10,0 -.1F db 'Not Menuet/Kolibri executable.',10,0 -.20 db 'Too many processes.',10,0 -load_succ_msg db 'Program loaded successfully! PID=%4X. Use "g" to run.',10,0 -need_debuggee db 'No program loaded. Use "load" command.',10,0 -aAlreadyLoaded db 'Program is already loaded. Use "terminate" or "detach" commands',10,0 -terminated_msg db 'Program terminated.',10,0 -aException db 'Debugged program caused an exception %2X. ' -aSuspended db 'Suspended',10,0 -aContinued db 'Continuing',10,0 -aRunningErr db 'Program is running',10,0 -read_mem_err db 'ERROR: cannot read process memory!!!',10,0 + dd .1, 0, .3, 0, .5, .6, 0, 0, .9, .A, 0, 0, 0, 0, 0, 0 + dd 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, .1E, .1F, .20 +.1 db 'HD undefined.',10,0 +.3 db 'Unknown FS.',10,0 +.5 db 'File not found.',10,0 +.6 db 'Unexpected EOF.',10,0 +.9 db 'FAT table corrupted.',10,0 +.A db 'Access denied.',10,0 +.1E db 'No memory.',10,0 +.1F db 'Not Menuet/Kolibri executable.',10,0 +.20 db 'Too many processes.',10,0 +load_succ_msg db 'Program loaded successfully! PID=%4X. Use "g" to run.',10,0 +need_debuggee db 'No program loaded. Use "load" command.',10,0 +aAlreadyLoaded db 'Program is already loaded. Use "terminate" or "detach" commands',10,0 +terminated_msg db 'Program terminated.',10,0 +aException db 'Debugged program caused an exception %2X. ' +aSuspended db 'Suspended',10,0 +aContinued db 'Continuing',10,0 +aRunningErr db 'Program is running',10,0 +read_mem_err db 'ERROR: cannot read process memory!!!',10,0 aBreakpointLimitExceeded db 'Breakpoint limit exceeded',10,0 -aBreakErr db 'Cannot activate breakpoint, it will be disabled',10,0 -aDuplicateBreakpoint db 'Duplicate breakpoint',10,0 -aInvalidBreak db 'Invalid breakpoint number',10,0 -OnBeErrMsg db 'There is already enabled breakpoint on this address',10,0 -aBreakNum db '%2X: at %8X',0 -aMemBreak1 db '%2X: on ',0 -aMemBreak2 db 'read from ',0 -aMemBreak3 db 'access of ',0 -aMemBreak4 db 'byte',0 -aMemBreak5 db 'word',0 -aMemBreak6 db 'dword',0 -aMemBreak7 db ' at %8X',0 -aOneShot db ', one-shot',0 -aDisabled db ', disabled',0 -aBreakStop db 'Breakpoint #%2X',10,0 -aUserBreak db 'int3 command at %8X',10,0 -;dbgmsg_str db 'Debug message for process %4X.',10,0 -aInvAddr db 'Invalid address',10,0 -NoPrgLoaded_str db 'No program loaded' +aBreakErr db 'Cannot activate breakpoint, it will be disabled',10,0 +aDuplicateBreakpoint db 'Duplicate breakpoint',10,0 +aInvalidBreak db 'Invalid breakpoint number',10,0 +OnBeErrMsg db 'There is already enabled breakpoint on this address',10,0 +aBreakNum db '%2X: at %8X',0 +aMemBreak1 db '%2X: on ',0 +aMemBreak2 db 'read from ',0 +aMemBreak3 db 'access of ',0 +aMemBreak4 db 'byte',0 +aMemBreak5 db 'word',0 +aMemBreak6 db 'dword',0 +aMemBreak7 db ' at %8X',0 +aOneShot db ', one-shot',0 +aDisabled db ', disabled',0 +aBreakStop db 'Breakpoint #%2X',10,0 +aUserBreak db 'int3 command at %8X',10,0 +;dbgmsg_str db 'Debug message for process %4X.',10,0 +aInvAddr db 'Invalid address',10,0 +NoPrgLoaded_str db 'No program loaded' NoPrgLoaded_len = $ - NoPrgLoaded_str -aRunning db 'Running' -aPaused db 'Paused' -aPoint db 0x1C -aMinus db '-' -aColon db ':' -aSpace db ' ' -aQuests db '??' -aDots db '...' -aParseError db 'Parse error',10,0 -aDivByZero db 'Division by 0',10,0 -calc_string db '%8X',10,0 -aNoMemory db 'No memory',10,0 -aSymbolsLoaded db 'Symbols loaded',10,0 -aUnaligned db 'Unaligned address',10,0 -aEnabledBreakErr db 'Enabled breakpoints are not allowed',10,0 -aInterrupted db 'Interrupted',10,0 -aUnpacked db 'Unpacked successful!',10,0 -aPacked1 db 'Program is probably packed with ',0 -aPacked2 db '.',10,'Try to unpack automatically? [y/n]: ',0 -aY_str db 'y',10,0 -aN_str db 'n',10,0 -mxp_nrv_name db 'mxp_nrv',0 -mxp_name db 'mxp',0 -mxp_lzo_name db 'mxp_lzo',0 -mtappack_name db 'mtappack',0 -flags db 'CPAZSDO' -flags_bits db 0,2,4,6,7,10,11 +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 ':' +aSpace db ' ' +aQuests db '??' +aDots db '...' +aParseError db 'Parse error',10,0 +aDivByZero db 'Division by 0',10,0 +calc_string db '%8X',10,0 +aNoMemory db 'No memory',10,0 +aSymbolsLoaded db 'Symbols loaded',10,0 +aUnaligned db 'Unaligned address',10,0 +aEnabledBreakErr db 'Enabled breakpoints are not allowed',10,0 +aInterrupted db 'Interrupted',10,0 +aUnpacked db 'Unpacked successful!',10,0 +aPacked1 db 'Program is probably packed with ',0 +aPacked2 db '.',10,'Try to unpack automatically? [y/n]: ',0 +aY_str db 'y',10,0 +aN_str db 'n',10,0 +mxp_nrv_name db 'mxp_nrv',0 +mxp_name db 'mxp',0 +mxp_lzo_name db 'mxp_lzo',0 +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=' - db 'ECX=' - db 'EDX=' - db 'ESI=' - db 'EDI=' - db 'EBP=' - db 'ESP=' - db 'EIP=' - db 'EFLAGS=' + db 'EAX=' + db 'EBX=' + db 'ECX=' + db 'EDX=' + db 'ESI=' + db 'EDI=' + db 'EBP=' + 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 +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 - -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 +include 'disasm_tbl.inc' reg_table: - db 2,'al',0 - db 2,'cl',1 - db 2,'dl',2 - db 2,'bl',3 - db 2,'ah',4 - db 2,'ch',5 - db 2,'dh',6 - db 2,'bh',7 - db 2,'ax',8 - db 2,'cx',9 - db 2,'dx',10 - db 2,'bx',11 - db 2,'sp',12 - db 2,'bp',13 - db 2,'si',14 - db 2,'di',15 - db 3,'eax',16 - db 3,'ecx',17 - db 3,'edx',18 - db 3,'ebx',19 - db 3,'esp',20 - db 3,'ebp',21 - db 3,'esi',22 - db 3,'edi',23 - db 3,'eip',24 - db 0 + db 2,'al',0 + db 2,'cl',1 + db 2,'dl',2 + db 2,'bl',3 + db 2,'ah',4 + db 2,'ch',5 + db 2,'dh',6 + db 2,'bh',7 + db 2,'ax',8 + db 2,'cx',9 + db 2,'dx',10 + db 2,'bx',11 + db 2,'sp',12 + db 2,'bp',13 + db 2,'si',14 + db 2,'di',15 + db 3,'eax',16 + db 3,'ecx',17 + db 3,'edx',18 + db 3,'ebx',19 + db 3,'esp',20 + db 3,'ebp',21 + db 3,'esi',22 + db 3,'edi',23 + db 3,'eip',24 + db 0 IncludeIGlobals fn70_read_block: - dd 0 - dq 0 - dd ? - dd ? - db 0 - dd ? + dd 0 + dq 0 + dd ? + dd ? + db 0 + dd ? fn70_attr_block: - dd 5 - dd 0,0,0 - dd fileattr - db 0 - dd ? + dd 5 + dd 0,0,0 + dd fileattr + db 0 + dd ? fn70_load_block: - dd 7 - dd 1 -load_params dd 0 - dd 0 - dd 0 + dd 7 + dd 1 +load_params dd 0 + dd 0 + dd 0 i_end: loadname: - db 0 - rb 255 + db 0 + rb 255 -symbolsfile rb 260 +symbolsfile rb 260 prgname_ptr dd ? prgname_len dd ? IncludeUGlobals -dbgwnd dd ? +dbgwnd dd ? -messages rb messages_height*messages_width -messages_pos dd ? +messages rb messages_height*messages_width +messages_pos dd ? -cmdline rb cmdline_width+1 -cmdline_len dd ? -cmdline_pos dd ? -curarg dd ? +cmdline rb cmdline_width+1 +cmdline_len dd ? +cmdline_pos dd ? +curarg dd ? -was_temp_break db ? +cmdline_prev rb cmdline_width+1 -dbgbufsize dd ? -dbgbuflen dd ? -dbgbuf rb 256 +was_temp_break db ? -fileattr rb 40 +dbgbufsize dd ? +dbgbuflen dd ? +dbgbuf rb 256 + +fileattr rb 40 needzerostart: context: -_eip dd ? -_eflags dd ? -_eax dd ? -_ecx dd ? -_edx dd ? -_ebx dd ? -_esp dd ? -_ebp dd ? -_esi dd ? -_edi dd ? +_eip dd ? +_eflags dd ? +_eax dd ? +_ecx dd ? +_edx dd ? +_ebx dd ? +_esp dd ? +_ebp dd ? +_esi dd ? +_edi dd ? oldcontext rb $-context -dumpread dd ? -dumppos dd ? -dumpdata rb dump_height*10h +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 ; breakpoint structure: ; dword +0: address @@ -6176,27 +2892,30 @@ dumpdata rb dump_height*10h ; byte +5: overwritten byte ; for DRx breaks: flags + (index shl 6) breakpoints_n = 256 -breakpoints rb breakpoints_n*6 -drx_break rd 4 +breakpoints rb breakpoints_n*6 +drx_break rd 4 -disasm_buf_size dd ? +disasm_buf_size dd ? -symbols dd ? -num_symbols dd ? +symbols dd ? +num_symbols dd ? -bReload db ? +bReload db ? needzeroend: -disasm_buffer rb 256 -disasm_start_pos dd ? -disasm_cur_pos dd ? -disasm_cur_str dd ? -disasm_string rb 256 +disasm_buffer rb 256 +disasm_start_pos dd ? +disasm_cur_pos dd ? +disasm_cur_str dd ? +disasm_string rb 256 -i_param rb 256 +i_param rb 256 ; stack - align 400h - rb 400h + align 400h + rb 400h used_mem: + +; vim: ft=fasm tabstop=4 + diff --git a/programs/develop/mtdbg/parser.inc b/programs/develop/mtdbg/parser.inc new file mode 100644 index 0000000000..33ed083c7e --- /dev/null +++ b/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 + diff --git a/programs/develop/mtdbg/sort.inc b/programs/develop/mtdbg/sort.inc index 359f043fa5..025b447b75 100644 --- a/programs/develop/mtdbg/sort.inc +++ b/programs/develop/mtdbg/sort.inc @@ -1,15 +1,18 @@ -; Сортировка 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 pop eax dec eax jnz @b -@@: + + @@: cmp ecx, 1 jz .done mov esi, 1 @@ -19,10 +22,11 @@ sort: mov eax, 1 call .restore jmp @b -.done: + + .done: ret -.exchange: + .exchange: push eax ecx mov eax, [edx+esi*4-4] mov ecx, [edx+edi*4-4] @@ -31,10 +35,10 @@ sort: pop ecx eax ret -.restore: + .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,14 +46,15 @@ sort: 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 -.need_xchg: + jbe .donerr + + .need_xchg: cmp esi, ecx jz .do_xchg push esi @@ -58,10 +63,15 @@ sort: call ebx pop esi sbb esi, -1 -.do_xchg: + + .do_xchg: mov edi, eax call .exchange mov eax, esi jmp .restore -.doner: + + .donerr: ret + +; vim: ft=fasm tabstop=4 +