/debug

Clone of the MS-DOS DEBUG command

Primary LanguageAssembly

 1. About

    This is a clone of the MS-DOS DEBUG command. Some minor things aren't
    implemented. OTOH it has many features not available in the original
    MS DEBUG. For details see below.


 2. Files Overview

    The files in this distribution are:

    debug.com     the executable binary.
    debugx.com    a DPMI aware version of Debug.
    debxxvdd.dll  a Win32 dll (VDD) loaded if debugx runs in a Windows XP 
                  NTVDM "DOS box". Makes debugx's L and W command work with
                  sectors on this platform.
    debug.asm     Assembler source code for both debug.com and debugx.com.
                  Assemble with JWasm or Masm (see Make.BAT).
    debugtbl.inc  include file for debug.asm, contains tables for Debug's
                  internal assembler and disassembler command.
    instr.*       input data for mktables.
    mktables.c    C program to compile the internal instruction-set
                  tables into source file debugtbl.inc. It's supposed to
                  be translated with Open Watcom's 16bit compiler WCC.
    readme.txt    this file.
    debug.txt     a MS-Debug tutorial originally written by Michael Webster,
                  extended to describe all additional features of DEBUG/X.
    SAMPLES       contains samples of 16 and 32-bit DPMI clients in Masm
                  and Nasm syntax.

    Note: files mktables.c and instr.* are to be removed in one of the next
    versions of Debug. Then file debugtbl.inc is supposed to be modified
    directly if new instructions are to be supported..


 3. Missing/Added Features

  a. The following are not implemented:

   - Loading of .HEX files.

  b. This debugger extends the MS-Debug in the following ways:

   - The assembler and disassembler support all publicly documented
     instructions for Intel chips through the Pentium Pro (P6), except for
     the MMX instructions (as for debugx, MMX is partially supported since
     v1.18). The assembler and disassembler inform you if any instruction is 
     inappropriate for the current processor.

   - FPU Opcodes are supported.

   - The current processor (for the purposes of assembler and disassembler
     warnings, above) can be declared to be something else via the following
     commands:

        m [x] set current processor.
              x=0 current processor is 8088.
              x=1..6 current processor is 80x86. 80586 is a Pentium and
              80686 is a Pentium Pro.
              no argument = print current CPU/FPU types.
        mc [2|N] set math coprocessor. 
             2 = math coprocessor is a 287 (only valid if current
                 processor is a 386).
             N = math coprocessor is absent
             no argument = math coprocessor is present

   - 'r register [value]' accepts 32-bit register names (for cpu 80386+).

   - You can do `r cx 1234' instead of having to put the `1234' on a
     separate line.

   - 'rn' displays FPU register status (currently for cpu 80386+ only)
      Just the raw hex values of the registers are displayed, though.

   - 'rx' switches among 8086 and 80386 register display (for cpu 80386+).

   - When doing `debug < file', debug will not hang if it reaches an end of
     file before encountering a `q' command.

   - This debugger saves and restores the program's Control-C and critical
     error interrupts, providing for better isolation between the debugger
     and the program being debugged.

   - 'tm 0|1' sets trace command mode, 0 = process INTs (default),
     1 = single-step INTs (the MS-DOS Debug compatible mode).

   - 'xr' allows to reallocate an EMS handle and 'xa' allows to allocate
     an "empty" EMS handle (with zero pages) - but only if an EMM v4.0
     is present.  

   - Besides 'i' and 'o' exist the variations 'iw', 'id', 'ow' and 'od'
     to read/write a WORD or DWORD value from/to a port [DWORD values
     require a 80386+ cpu].

   - 'h' can handle dword values.

   - register names can be used anywhere where a number is expected as
     input. That is, things like "u cs:ip" do work.

   - 'dm' displays the DOS memory control block (MCB) chain and the
     current PSP.

   - if DOS has set its InDOS flag, DEBUG will avoid to use int 21h
     internally, which allows to single-step through DOS code.

   - 'd', 't' and 'u' are automatically repeated if a blank line is
     entered.

   c. A DPMI aware version of the debugger, DEBUGX, is available, with the
      following additional features:

   - besides real-mode applications it can debug both 16-bit and 32-bit
     DPMI clients. 
     [To debug DPMI clients a DPMI host has to be installed. Tested with
      cwsdpmi, hdpmi, WinXP NTVDM, 32rtm. In DosEmu and Windows 95/98/ME
      DOS boxes it is required to single-step through the initial switch
      to protected-mode, else DEBUGX will loose control of the debuggee.]

   - 'dl': display LDT descriptor(s) (in protected-mode only)

   - 'di': display interrupt vector(s)

   - 'dx': display extended memory (read via Int 15h, ah=87h). Requires a
     80386 cpu. 'dx' is automatically repeated if a blank line is entered.

   - 'rn' displays FPU registers in "readable" format.

   - when running in a Windows XP DOS bos, DEBUGX will try to load and use
     DEBXXVDD.DLL. This DLL will allow DEBUGX to successfully execute its
     low-level disk access commands L and W in this OS - if the user has
     administrator rights. DEBXXVDD.DLL is public domain, the source can
     be downloaded from http://www.japheth.de/Download/debxxvdd.zip. Please
     be aware that you can do severe damage to your disk data if you use
     those low-level functions without knowing what you are doing.

   - 'rm' displays MMX registers.


 4. History

    0.95e [11 January 2003]  Fixed a bug in the assember.
    0.95f [10 September 2003]  Converted to NASM; fixed some syntax
       incompatibilities.
    0.98 [27 October 2003]  Added EMS commands and copyright conditions.
    ------- changes below were done by me, japheth
    0.99 [27 Septemb 2006]
       - bugfix: IF was not displayed correctly.
       - FS and GS registers displayed if cpu is 80386+.
       - RX displays the standard 32bit registers.
       - R register [value] understands the standard 32bit registers.
    0.99a [28 Septemb 2006] 
       - bugfix: JECXZ had wrong prefix (66h, should be 67h).
       - A and D understand the 32bit opcodes LOOP(Z|NZ|E|NE)D.
    0.99b [29 Septemb 2006]
       - L and W now work with FAT32 drives.
    0.99c [29 Septemb 2006]
       - RX changed. Now it toggles 16/32 bit register dump.
       - RN displays floating point register status.
    0.99d [02 October 2006]
       - bugfix: RN displayed error-pointer registers wrong.
    0.99e [12 October 2006]
       - XR command added to reallocate EMS handle.
       - XA command allows to allocate zero pages on EMS 4.0.
       - TM [0|1] added to be able to switch T to the ms-dos debug
         compatible behaviour (that is, T jumps into 'INT xx').
    0.99f [17 October 2006]
       - debug's EMS functions may work even with a "hidden" EMM.
       - bugfix: display of mappable pages didn't account for amount of
         these pages == 0.
    0.99g [25 October 2006]
       - bugfix: U was unable to recognise [ESP] related memory operands
         (i.e. mov eax,[esp]).
    0.99h [07 November 2006]
       - bugfix: R trying to display content of effective address has
         caused a GPF in v86-mode if this address was FFFFh of FFFDh.
       - IW, ID, OW and OD implemented.
    0.99i [14 November 2006]
       - bugfix: a child PSP was created but not terminated, causing files
         not to be closed. It became obvious if stdin and/or stdout were
         redirected to files ("C:\>DEBUG >yyy")
    0.99j [16 November 2006]
       - bugfix: using T if current instruction is an INT xx (and trace
         mode == 0) stopped debuggee one instruction *after* the INT (due
         to a x86 design weakness).
       - bugfix: the 0.99i bugfix had some problems on FreeDOS.
    1.00 [25 November 2006]
       - bugfix: debuggee's psp was saved after program load only, but
          this has to be done every time the debugger regains control.
       - There is now a DPMI aware version of debug, DEBUGX, createable
         from the source.
       - bugfix in disassembler: RETF did not have a corresponding RETFD
         entry (to switch with prefix 66h)
    1.01 [26 November 2006]
       - bugfix: MC2 didn't work.
       - Register names can be used anywhere where a number is expected
         as input.
    1.02 [29 November 2006]
       - bugfix: 'I d' and 'O d' didn't work because the parser assumed
         ID and OD commands.
       - DEBUGX bugfix: T= and G= didn't work in protected-mode.
       - bugfix: loading a file at another location than cs:100h was not
         supported in versions 0.99 - 1.01.
       - Debugger can be loaded high.
    1.03 [1 February 2007]
       - DEBUG bugfix: previous version of DEBUG.COM did not reliably reset
         "auto-reset" breakpoints (used for processing INTs).
       - DEBUGX: DI now works in real-mode as well.
       - DM command added.
    1.04 [2 March 2007]
       - making single-step through the DOS kernel possible.
    1.05 [1 April 2007] 
       - program exit code displayed.
       - DM displays the PSP "name".
       - autorepeat for D, DX, T and U added.
       - DEBUGX: DX added.
    1.06 [21 May 2007] 
       - bugfix: SMSW/LMSW in assembler didn't accept a 32bit operand.
       - bugfix: OW/OD didn't accept the value parameter.
       - key '-' supported in E command to step backward.
    1.07 [3 November 2007]
       - bugfix: entering ranges with upper bound was refused.
       - DEBUGX bugfix: if help cmd waited for a keypress, it displayed
         garbage if cpu was in protected-mode and CWSDPMI was used.
       - Tracing into an INT (TM 1) now works if interrupt vector points
         to ROM code.
    1.08 [23 November 2007]
       - bugfix: segment prefix was lost for mnemonics without arguments
         (patch by Oleg O. Chukaev).
    1.09 [30 December 2007]
       - DEBUGX: several bugfixes for A and U handling 32bit code segments.
       - bugfix: U split lines if instruction size exceeded 6.
       - bugfix: M didn't work with "upper bound" ranges.
       - DEBUGX change: in 32bit code segments, U displayed ECX as first
         operand for LOOPx to indicate that ECX is used instead of CX.
         Now a 'D' is attached to the opcode (LOOPxD, x=Z|NZ|E|NE) instead.
       - bugfix: A didn't choose the short (=signed) form of arith
         instructions (adc, add, ...) if E/AX was first operand.
    1.10 [25 January 2008]
       - DEBUGX: to intercept DPMI initial switches to protected-mode,
         int 2Fh is now hooked later. This allows to debug applications
         which install their own DPMI host during initialization.
       - DEBUGX: DL understands an optional "count" argument.
    1.11 [06 February 2008]
       - bugfix: debugger lost debuggee's HiWord(EFL) in real-mode.
       - bugfix: if debuggee set CR0 AM bit and EFL AC flag, an
         exception 11h occured in the debugger.
       - DEBUGX bugfix: G command was unable to set/restore breakpoints if
         HiWord(EIP) wasn't clear.
       - DEBUGX bugfix: U ignored HiWord of argument's offset part.
       - DEBUGX bugfix: E ignored HiWord of argument's offset part.
       - DEBUGX bugfix: M didn't accept first argument's offset > FFFF.
       - DEBUGX bugfix: running in NTVDM and pressing Ctrl-C while debuggee
         is in protected-mode no longer drops to real-mode.
       - DEBUGX: RN now renders floating point register content properly
         (DEBUG still just displays raw hex format for size reasons).
       - DEBUGX: DI got an optional 'count' parameter.
       - DEBUGX: D default segment part is checked if it is valid in pmode
         and changed to value of client's DS if no.
    1.12 [14 February 2008]
       - bugfix: length 0 in range wasn't interpreted as 64 kB.
       - DEBUGX bugfix: E in prompt mode didn't work with 32bit offsets.
       - DEBUGX bugfix: L and W didn't work with buffer offset >= 10000h.
       - DEBUGX bugfix: Q while debuggee was in pmode caused a GPF if
         HiWord(EIP) or HiWord(ESP) wasn't zero.
       - DEBUGX: DI additionally displays DPMI exception vectors.
       - DEBUGX: when running in NTVDM, DEBXXVDD.DLL will be loaded, which
         will make L and W work with sectors on this platform.
       - DEBUGX: DM now works in protected-mode as well.
       - now all commands are described in DEBUG.TXT.
    1.13 [27 February 2008]
       - DEBUG bugfix: L and W with sectors worked for DEBUGX only in v1.12.
    1.14 [12 January 2009]
       - DEBUGX bugfix: 'D ip' caused a syntax error.
       - DEBUGX bugfix: if debugger stepped into an INT in protected-mode,
         the carry flag was cleared.
       - H improved.
       - source converted to Masm syntax.
       - samples in Masm syntax added.
    1.15 [12 April 2009]
       - bugfix: in v1.04 - v1.14, restoring debuggee's interrupt vectors
         23+24 caused a memory corruption (8 bytes) due to a wrong segment
         register value.
    1.16 [20 April 2009]
       - bugfix: 'mnc' command was rejected. Syntax changed to 'mc n'.
       - bugfix: in v1.14-1.15, 'g' didn't reliably detect whether a bp was
         external.
       - bugfix: 'g' command could get confused by opcode CD 03.
       - DEBUGX bugfix: 'a' command ignored hiword of current offset in
         32bit segments.
       - DEBUGX bugfix: when debuggee was in protected-mode and then
         terminated during execution of 'p' or 't' command, the try to
         restore an internal bp may have caused memory corruption.
    1.17 [28 April 2009]
       - bugfix: R <32bit register> <new value> didn't work in v1.16.
       - bugfix: DPMICL16.ASM wasn't a sample for a 16bit DPMI client.
       - bugfix: under some conditions 'm' was silently rejected.
    1.18 [18 May 2009]
       - DEBUGX bugfix: RN required a 80386 cpu.
       - DEBUGX bugfix: RN always assumed that current mode is real-mode.
         However, the layout of FSAVE/FRSTOR differs for protected-mode.
       - bugfix: 'A' command didn't accept a semi-colon right after the
         mnemonic (example: clc;)
       - if cpu is 80386+, the 32bit version of FSAVE/FRSTOR is used now,
         which improves display of the FPU status.
       - 'r' command: EFL added to 386 register display.
       - for FLDENV, FSTENV, FSAVE and FRSTOR, 16/32 bits variants with
         suffixes W/D were added: FLDENVW/FLDENVD, FSTENVW/FSTENVD, ...
       - DEBUGX: 'rm' command added to display MMX registers.
       - DEBUGX: instructions MOVD, MOVQ, EMMS added to assembler and 
         disassembler.
       - layout of tables in debugtbl.inc modified to make them use
         symbolic constants and addresses. This allows to modify this
         file directly.


 5. Copyright

    This program is copyrighted, but feel free to distribute and use it
    as you wish.  For full copyright conditions, see the file debug.asm.

    Paul Vojta
    vojta@math.berkeley.edu