A Guide to DEBUG
(Page Two)
A DEBUG Tutorial
Copyright©2005,2007 by Daniel B. Sedory
This page
may be freely copied for PERSONAL use ONLY !
( It may NOT be used for ANY other purpose unless you have
first contacted and received permission
from the author! )
For a reminder of all the commands (and most of the parameters) that are available while inside of DEBUG, simply enter a question mark (?) at the DEBUG prompt; when using DOS 5.0 or later. ( Note: Expanded Memory commands are rarely if ever used and will not be discussed here.)
-? assemble A [address] compare C range address dump D [range] enter E address [list] fill F range list go G [=address] [addresses] hex H value1 value2 (Learn 2's Complement!) input I port load L [address] [drive] [firstsector] [number] move M range address name N [pathname] [arglist] output O port byte proceed P [=address] [number] quit Q . . . . . . . . . (Learn this first!) register R [register] search S range list trace T [=address] [number] unassemble U [range] write W [address] [drive] [firstsector] [number]
H o w t o
u s e t h e
C O M M A N D S
NOTE: Parameters listed in brackets ( [ ] ) are optional.
Optional parameters usually
indicate there are a number of different ways that a command can be used.
I've listed the meanings of all the parameters here for you:
address - Memory location specified in hexadecimal. You can use either a
simple Offset all by itself (in which case, the present CS 'Code Segment'
will be assumed), or you can enter the full Segment:Offset location using
either all hex numbers or substituting the name of a segment register for a
number. Leading zeros are not required; thus 1F all by itself would be the
location 'CS:001F' ( CS meaning whatever the CS happened to be at the time
you entered this ). Examples:
100 DS:12 SS:0 198A:1234For a detailed discussion, see: Segment:Offset notation.
e 100 31 C0 B4 09 BA 50 02 CD 21 B8 4C 00 CD 21 e 250 'This is an ASCII data string.$'
number - Remember that all numbers and values used in any DEBUG commands are understood as being Hexadecimal only! That includes the number of sectors in the LOAD or WRITE commands and even the number of instructions you want DEBUG to step through in the TRACE or PROCEED commands. It's all HEX all the time in here!
NOTE: In the Examples below, commands which are entered by a user are shown in bold type; data displayed in response by DEBUG is in normal type. DEBUG (from MS-DOS 5.0 or later (which is true for the DEBUG version used by Windows XP) will display the following usage message, if you enter debug /? at a DOS prompt:
C:\WINDOWS>debug /? Runs Debug, a program testing and editing tool. DEBUG [[drive:][path]filename [testfile-parameters]] [drive:][path]filename Specifies the file you want to test. testfile-parameters Specifies command-line information required by the file you want to test.
Quit: Q
Immediately quits (exits) the Debug program! No questions ever asked... should be the first command you remember along with the "?" command.
Back to TOCA very simple (add and subtract only) Hex calculator. Never forget that all numbers inside of DEBUG are always Hexadecimal. Enter two Hex values (no more than four digits each) and DEBUG shows first the SUM, then the DIFFERENCE of those values. Examples:
Hex: H value1 value2
-h aaa 531 -h fff 3 -h dbf ace 0FDB 0579 1002 0FFC 188D 02F1 - - -
Differences are always the second value subtracted from the first; AAA - 531 = 579. There are no carries past four digits.
Two's Complement arithmetic is always used in this calculator, so think of it as being limited to a maximum of plus 7FFFh (+ 32,767) or a minimum of minus 8000h (- 32,768). Positive values are represented by exactly the same digits as their numbers for 0000h through 7FFFh. A minus 7FFFh, however, is represented by the Hex digits 8001, and a minus 1h (-1) is represented by the Hex digits FFFF. Thus, the output of DEBUG after entering "h 4 fffc" would be a zero and an 8, because FFFC represents a minus 4h (-4) and 4 - (-4) = 8. Examples:
-h 4 fffc -h 100 123 -h 7fff 8000 0000 0008 0223 FFDD FFFF FFFF - - -Notice that the difference between 100h and 123h is FFDD; what does that represent? To find the numerical value of a Two's Complement number, first invert every bit (or find its logical inverse); that would be 0022, then add 1. So, this represents a negative 23h. Both the sum and the difference of 7FFFh and 8000h are a negative 1 (or FFFF). You can, of course, think of the sums as having nothing to do with a Two's Complement notation; thus 7FFFh + 8000h = FFFFh (32,767 + 32,768 = 65,535). This will even hold true for the differences if the second value is less than the first. But as soon as the difference produces a negative number, it must be represented in Two's Complement.
Back to TOC
Dump: D [range] D [address] [length]
Displays the contents of a block
of memory. The Memory locations near the beginning of Segment C000
(even under Windows 2000/XP) should display information about the kind of video
card installed on your PC. The first example below shows what a Matrox video
card on our system displayed.
Examples:
-d c000:0010 C000:0010 24 12 FF FF 00 00 00 00-60 00 00 00 00 20 49 42 $.......`.... IB C000:0020 4D 20 43 4F 4D 50 41 54-49 42 4C 45 20 4D 41 54 M COMPATIBLE MAT C000:0030 52 4F 58 2F 4D 47 41 2D-47 31 30 30 20 56 47 41 ROX/MGA-G100 VGA C000:0040 2F 56 42 45 20 42 49 4F-53 20 28 56 31 2E 32 20 /VBE BIOS (V1.2 C000:0050 29 00 87 DB 87 DB 87 DB-87 DB 87 DB 87 DB 87 DB )............... C000:0060 50 43 49 52 2B 10 01 10-00 00 18 00 00 00 00 03 PCIR+........... C000:0070 40 00 12 10 00 80 00 00-38 37 34 2D 32 00 FF FF @.......874-2... C000:0080 E8 26 56 8B D8 E8 C6 56-74 22 8C C8 3D 00 C0 74 .&V....Vt"..=..t -
-d 100 130 xxxx:0100 EB 24 0D 0A 54 68 69 73-20 69 73 20 6D 79 20 66 .$..This is my f xxxx:0110 69 72 73 74 20 44 45 42-55 47 20 70 72 6F 67 72 irst DEBUG progr xxxx:0120 61 6D 21 0D 0A 24 B4 09-BA 02 01 CD 21 B4 00 CD am!..$......!... xxxx:0130 21 ! -The last example above, is what you'd see after entering the code under the Assemble command. We could just as easily have used the length option with the command 'd 100 l31' (that's an 'L' in front of the "31") to produce the same results above. The following example shows only the '$'-terminated display string, which has a length of 24h bytes (remember numbers in DEBUG are always hexadecimal); so, that's 36 in decimal:
-d 102 l24 xxxx:0100 0D 0A 54 68 69 73-20 69 73 20 6D 79 20 66 ..This is my f xxxx:0110 69 72 73 74 20 44 45 42-55 47 20 70 72 6F 67 72 irst DEBUG progr xxxx:0120 61 6D 21 0D 0A 24 am!..$ - Back to TOC
Search: S range list
Searches within a range of addresses for a pattern of one or more byte values given in a list. The list can be comprised of numbers or character strings enclosed by matching single or double quote marks. [ NOTE: In the examples below, if you do find the same data on your computer, the locations could easily vary from ours! ]
Examples:
-s fe00:0 ffff "BIOS" FE00:0021 FE00:006F -d fe00:0 FE00:0000 41 77 61 72 64 20 53 6F-66 74 77 61 72 65 49 42 Award SoftwareIB FE00:0010 4D 20 43 4F 4D 50 41 54-49 42 4C 45 20 34 38 36 M COMPATIBLE 486 FE00:0020 20 42 49 4F 53 20 43 4F-50 59 52 49 47 48 54 20 BIOS COPYRIGHT FE00:0030 41 77 61 72 64 20 53 6F-66 74 77 61 72 65 20 49 Award Software I FE00:0040 6E 63 2E 6F 66 74 77 61-72 65 20 49 6E 63 2E 20 nc.oftware Inc. FE00:0050 41 77 03 0C 04 01 01 6F-66 74 77 E9 12 14 20 43 Aw.....oftw... C FE00:0060 1B 41 77 61 72 64 20 4D-6F 64 75 6C 61 72 20 42 .Award Modular B FE00:0070 49 4F 53 20 76 34 2E 35-31 50 47 00 DB 32 EC 33 IOS v4.51PG..2.3 -s 0:0 dff 'A20' 0000:0C42 -d 0:c40 0000:0C40 0D 0A 41 32 30 20 68 61-72 64 77 61 72 65 20 65 ..A20 hardware e 0000:0C50 72 72 6F 72 2E 20 20 43-6F 6E 74 61 63 74 20 74 rror. Contact t 0000:0C60 65 63 68 6E 69 63 61 6C-20 73 75 70 70 6F 72 74 echnical support 0000:0C70 20 74 6F 20 69 64 65 6E-74 69 66 79 20 74 68 65 to identify the 0000:0C80 20 70 72 6F 62 6C 65 6D-2E 0D 0A 24 1A 00 BA F6 problem...$.... -s 0:0 dff 43 4f 4d 0000:0774 0000:07C2 0000:07D4 0000:07E6 -d 0:770 0000:0770 7A 02 A6 02 43 4F 4D 31-20 20 20 20 8E 00 70 00 z...COM1 ..p. 0000:0780 C0 A0 7A 02 91 02 4C 50-54 31 20 20 20 20 A0 00 ..z...LPT1 .. 0000:0790 70 00 C0 A0 7A 02 98 02-4C 50 54 32 20 20 20 20 p...z...LPT2 0000:07A0 2D 01 70 00 C0 A0 7A 02-9F 02 4C 50 54 33 20 20 -.p...z...LPT3 0000:07B0 20 20 11 EA 27 27 3F FD-CA 00 70 00 00 80 7A 02 ..''?...p...z. 0000:07C0 AC 02 43 4F 4D 32 20 20-20 20 DC 00 70 00 00 80 ..COM2 ..p... 0000:07D0 7A 02 B2 02 43 4F 4D 33-20 20 20 20 00 00 6B 03 z...COM3 ..k. 0000:07E0 00 80 7A 02 B8 02 43 4F-4D 34 20 20 20 20 E8 D2 ..z...COM4 .. Back to TOCCompares two blocks of memory. If there are no differences, then DEBUG simply displays another prompt (-). Here's an example of what happens when there are differences:
Compare: C range address
-c 140 148 340 127D:0143 30 6D 127D:0343 127D:0146 10 63 127D:0346 127D:0148 49 30 127D:0348The bytes at locations 140 through 148 are being compared to those at 340 ( through 348, implied ); the bytes are displayed side by side for those which are different (with their exact locations, including the segment, on either side of them).
Back to TOCThis command can also be used to clear a whole segment of Memory as well as filling smaller areas with a continuously repeating phrase or single byte. Examples:
Fill: F range list
-f 100 12f 'BUFFER' -d 100 12f xxxx:0100 42 55 46 46 45 52 42 55-46 46 45 52 42 55 46 46 BUFFERBUFFERBUFF xxxx:0110 45 52 42 55 46 46 45 52-42 55 46 46 45 52 42 55 ERBUFFERBUFFERBU xxxx:0120 46 46 45 52 42 55 46 46-45 52 42 55 46 46 45 52 FFERBUFFERBUFFER -f 100 ffff 0
This last example fills almost all of the assigned Segment with zero bytes (which can also be thought of as clearing the Segment). You should use this command whenever you want to be sure that the bytes you'll be looking at in DEBUG's Segment are those you've manually entered or loaded; not just previously used code in memory! If you want to examine a file from a disk in a 'clean' Segment, you'll first have to start DEBUG without any filename, clear the Segment using: f 100 ffff 0 and then finally load the file using the Name (n) and Load (L) commands in that order.
NOTE: Filling (clearing) any bytes in the area from 00h through FFh of the Segment used by DEBUG can sometimes lead to problems; especially when file I/O is involved. DEBUG stores data for its own use in those locations, so we recommend that you never overwrite bytes in that area; unless you know for sure they won't be necessary!
Example: A student in an Assembly class was told to enter a string of commands under DEBUG, the last one being: JMP 0 which he was supposed to Trace (T) to the next command and then execute it. He was told it would be an INT 20 instruction. Well in most cases this is true, because DEBUG always sets the first two bytes of its working segment to "CD 20" for just this purpose. Let's test this out. First, open a new instance of DEBUG, then enter the following commands:
-f 100 ffff 0 [Zero-out 100 through FFFF] -e 100 e9 fd fe [Enters a 'JMP 0' at 100] -u 100 102 [Check for correct entry] xxxx:0100 E9FDFE JMP 0000 -r
AX=0000 BX=0000 CX=0000 DX==0000 SP=FFEE BP=0000 SI=0000 DI=0000
DS=xxxx ES=xxxx SS=xxxx CS=xxxx IP=0100 NV UP EI PL NZ NA PO NC
xxxx:0100 E9FDFE JMP 0000 -u 0 1 xxxx:0000 CD20 INT 20
If you don't see "INT 20" after entering "u 0 1", then restart DEBUG and try again.
-t [The "T"(Trace) command] AX=0000 BX=0000 CX=0000 DX=0000 SP=FFEE BP=0000 SI=0000 DI=0000 DS=xxxx ES=xxxx SS=xxxx CS=xxxx IP=0000 NV UP EI PL NZ NA PO NC xxxx:0000 CD20 INT 20 -p [Allways make sure you use a "P"(Proceed) command for Interrupts!] Program terminated normally -q [Quit]<
Well, this never worked for those students. Why? Because the teacher had mistakenly told them to Fill the whole segment with zero bytes (f 0 ffff 0), in essence telling them to delete the very instruction he'd wanted them to execute!
Back to TOCUsed to enter data or instructions (as machine code) directly into Memory locations.
Enter: E address [list]
-e ffcb d2The next two examples show that either single(') or double(") quote marks are acceptable for entering ASCII data. By allowing both forms, you can include the other type of quote mark within your entry string:
-e 200 'An "ASCII-Z string" is always followed by ' -e 22a "a zero-byte ('00h')." 00Now let's examine a string of 11 hex bytes that you can enter into Memory at locations CS:0100 and following:
-e 100 B4 09 BA 0B 01 CD 21 B4 00 CD 21This is actually machine code for a program that will display whatever ASCII characters it finds at locations CS:010B and following, until it encounters a byte value of 24h (a $ sign). If you really want to run this program, you should at least enter a 24h in the last byte of the Segment; that will make sure the program finally terminates there, if necessary! Just do the following:
-e ffff 24 -g =100And sooner or later, you'll see: "Program terminated normally" on the display screen.
Here's something a bit more interesting for you to try out: It's essentially the same program, but the data includes all of the byte values from 00h through FFh; except for 24h which we placed at the end of the last line. The DEBUG prompt symbol, - , has been purposely excluded from the lines below, so you can copy and paste the whole block all at once into DEBUG in a DOS-Window (some Help on using DOS-Window controls is here if you needed):
e 100 B4 09 BA 0B 01 CD 21 B4 00 CD 21 0D 0A 0D 0A 00 01 02 e 112 03 04 05 06 07 08 09 20 0B 0C 20 0E 0F 10 11 12 13 14 e 124 15 16 17 18 19 1A 1B 1C 1D 1E 1F 20 21 22 23 20 25 26 e 136 27 28 29 2A 2B 2C 2D 2E 2F 30 31 32 33 34 35 36 37 38 e 148 39 3A 3B 3C 3D 3E 3F 0D 0A 0D 0A 40 41 42 43 44 45 46 e 15a 47 48 49 4A 4B 4C 4D 4E 4F 50 51 52 53 54 55 56 57 58 e 16c 59 5A 5B 5C 5D 5E 5F 60 61 62 63 64 65 66 67 68 69 6A e 17e 6B 6C 6D 6E 6F 70 71 72 73 74 75 76 77 78 79 7A 7B 7C e 190 7D 7E 7F 0D 0A 0D 0A 80 81 82 83 84 85 86 87 88 89 8A e 1a2 8B 8C 8D 8E 8F 90 91 92 93 94 95 96 97 98 99 9A 9B 9C e 1b4 9D 9E 9F a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 aA aB aC aD aE e 1c6 aF b0 b1 b2 b3 b4 b5 b6 b7 b8 b9 bA bB bC bD bE bF 0D e 1d8 0A 0D 0A c0 c1 c2 c3 c4 c5 c6 c7 c8 c9 cA cB cC cD cE e 1ea cF d0 d1 d2 d3 d4 d5 d6 d7 d8 d9 dA dB dC dD dE dF e0 e 1fc e1 e2 e3 e4 e5 e6 e7 e8 e9 eA eB eC eD eE eF f0 f1 f2 e 20e f3 f4 f5 f6 f7 f8 f9 fA fB fC fD fE fF 0D 0A 0D 0A 24
The bytes 0Dh and 0Ah produce a Carriage Return and Linefeed on the display, so they were replaced by a 20h (a space) in the listing above. The 24h byte was, of course, moved to the end of the listing and its original location also turned into a space. A blank line was placed at the beginning of the output, and after every 64 bytes, by inserting the byte sequence '0D 0A 0D 0A' at those points in the listing above.
Therefore, when the program is run, we should see four separate lines of 64 characters each (a few of those being the blank spaces; as we mentioned above), right? Let's find out: Start DEBUG in a DOS-Window, copy and paste the lines above into DEBUG at its prompt symbol, - , then enter the following command:
g =100 ( 'g' followed by a SPACE, then '=100')
This will immediately run (see Go command) the program, displaying the lines mentioned above and lastly another line which states: "Program terminated normally" [ Do not exit DEBUG, and leave the DOS-Window open; we'll be making a 'patch' to this code below ].
Were you were surprised to find more than four spaces on the first line, or that there appear to be some missing characters at the end of that line? If so, then you might want to study about the Control Characters at the beginning of an ASCII chart. You'll also need to learn about Interrupts and what effect different BIOS and DOS Video Functions have on how the ASCII Characters are displayed. OK, I'll save you the time and tell you what happened:
First, the Zero byte displays as a blank space here. The
07 byte makes a beep or ding sound (but does not display
anything), 08 performs a BACKSPACE (erasing the 06 byte character) and
09 is a TAB -- which may jump up to eight columns to the right before
reaching the next 'Tab Stop.' But since it just happens to begin in column seven,
it only moves one column to the right where our program places the blank space
we substituted for 0Ah. Lastly, for some reason, when using Function
09 of INT 21h ("Display a string of characters until a '$' sign is encountered"),
the ESC character (1Bh; 27 decimal) doesn't display or do anything either.
So, after reaching the end of the first line, it appears as if five of the characters
were never displayed.
Now enter the following two lines into DEBUG (which contain more blank-space
substitutions) and run the program again, you'll see all of the displayable
characters output on the first line in their correct positions:
e 10F 00 01 02 03 04 05 06 20 20 20 20 0B 0C 20 e 11D 0E 0F 10 11 12 13 14 15 16 17 18 19 1A 20And all four rows should display evenly in size, including the last one, because the FFh (255 decimal) displays as a blank space! You can prove this by inserting another byte such as 2Eh (a period '.') right after the FFh byte. Since DEBUG can only overwrite a byte, not insert one, here's another patch which effectively moves the remainder of the program bytes (after the FFh) up by one location:
-n c:\temp\asciidsp.com -rcx CX0000 :121 [ Program Length = 220h - 100h + 1 = 121h ] -w
If you check the file properties of ASCIIDSP.COM, its size should be 289 bytes.
Go: G [=address] [addresses]Go is used to run a program and set breakpoints in the program's code.
Back to TOCCreates machine executable code in memory beginning at CS:0100 (or the specified address) from the 8086/8088 (and 8087) Assembly Language instructions which are entered. Although no Macro instructions nor labels are recognized, you can use the pseudo-instructions 'DB' and 'DW' (so you can use the DB opcode to enter ASCII data like this: DB 'This is a string',0D,0A ).
Assemble: A [address]
-a 100 xxxx:0100 jmp 126 ; Jump over data that follows: xxxx:0102 db 0d,0a,"This is my first DEBUG program!" xxxx:0123 db 0d,0a,"$" xxxx:0126 mov ah,9 ; Function 09 of Int 21h: xxxx:0128 mov dx,102 ; DS:DX -> $-terminated string. xxxx:012B int 21 ; Write String to STD Output. xxxx:012D mov ah,0 ; Function 00 of Int 21h: xxxx:012F int 21 ; Terminate Program. xxxx:0131 -g =100 This is my first DEBUG program! Program terminated normally -
NOTE: You can pipe simple 8086/8088 Assembly Language "scripts" into DEBUG (You can even include a semi-colon ';' followed by comments on most of its lines. For some odd reason though, these comments are not allowed on DB/DW lines!). For example, you can copy and paste the following into the DEBUG program (after entering the "a" command) and obtain the same results as above:
jmp 126 ; Jump over data that follows: db 0d,0a,"This is my first DEBUG program!" db 0d,0a,"$" ; End of string marker above: "$"=24h mov ah,9 ; Function 09 of Int 21h: mov dx,102 ; DS:DX -> $-terminated string. int 21 ; Write String to STD Output. mov ah,0 ; Function 00 of Int 21h: int 21 ; Terminate Program.
Back to TOCDisassembles machine instructions into 8086 Assembly code. Without the optional [range], it uses Offset 100 as its starting point, disassembles about 32 bytes and then remembers the next byte it should start with if the command is used again. ( The word 'about' was used above, because it may be necessary to finish with an odd-number of bytes greater than 32, depending upon the last type of instruction DEBUG has to disassemble. )
Unassemble: U [range]
Example: -u 126 12F xxxx:0126 B409 MOV AH,09 xxxx:0128 BA0201 MOV DX,0102 xxxx:012B CD21 INT 21 xxxx:012D B400 MOV AH,00 xxxx:012F CD21 INT 21 - Back to TOC
Input: I port
The use of I/O commands while running Windows9x/Me is just plain unreliable! This is especially true when trying to directly access hard disks! Under Win NT/2000/XP, the I/O commands are only an emulation; so don't trust them. Though the example below still works under Win2000/XP, it's most likely using some WinAPI code to show what's in the Windows clock area; not directly from an RTC chip.
Long ago (when DOS was the only OS for PCs), there
were dozens of BASIC programs that used I/O
commands for handling tasks through parallel and serial ports (e.g., to change
the font used by a printer or values in a modem's control registers). Under
real DOS, they can still be used for direct communications with keyboards or
a floppy drive's control chips along with many other hardware devices.
Here's an example of how to read the hours and minutes from a
computer's "real time clock" (RTC):
-o 70 04 <-- Check the hours. -i 71 18 <----- 18 hours (or 6 p.m.) -o 70 02 <-- Check the minutes. -i 71 52 <----- 52 minutesThe first space isn't necessary under most versions of DEBUG; so you can try to get away with just "o70" and "i71" instead. Here's a page of more complex examples dealing with hard drives and the ATA commands for reading info directly from a disk controller!
Back to TOC
Output: O port byte
See comments under the Input command.
Back to TOC
Load: L [address] [drive] [firstsector] [number]
or program! (See the N command for more on this)
This command will LOAD the selected
number of sectors from any disk's Logical Drive under the control of MS-DOS
or Windows into Memory. The address is the location in Memory the data
will be copied to (use only 4 hex digits to keep it within the memory allocated
to DEBUG), the drive number is mapped as: 0=A:, 1=B:, 2=C:, etc., firstsector
counts from ZERO to the largest sector in the volume and finally number
specifies in hexadecimal the total number of sectors
that will be copied into Memory (so a floppy disk with 0 through 2,879 sectors
would be: 0 through B3F
in Hex).
The terms 'Volume' or 'Logical Drive'
used in the definition above mean that you can not use the 'L'
command to load or examine the MBR, or any other sectors outside of the
Primary Volumes or Logical Drive Letters assigned by DOS or Windows! For
example (under Windows 9x/ME), if you enter the command: L
100 2 0 1 in DEBUG, instead of seeing the very first sector
on that hard disk (the MBR), you'll see the first sector of the Boot Record
for the Logical drive C: instead (the first partition that can accessed by a
compatible MS-DOS or Windows OS). This and the following comments about diskettes,
show that DEBUG has always been quite limited compared to a good disk editor
or the UNIX 'dd' program.
Load can still be useful in examining Floppy Disks even under Windows 2000/XP, but (unfortunately), only if the disk can be read by MS-DOS or Windows. Once again, this shows how limited DEBUG is compared to any utility that can view the raw data on either a hard drive or diskette. (For those of you who wish to examine the actual contents of a hard disk under WindowsXP, there are free disk editors, such as HxD, which allow you to do so.)
Unlike hard disks, the very first sector on a floppy
disk is an OS Boot sector. Here's what you might see from a Logical disk sector
and some dumps from a couple floppy disks.
Examples:
-l 100 2 0 1 [ the C: drive. ]
-d 100 10f
xxxx:0100 EB 58 90 4D 53 57 49 4E-34 2E 31 00 02 08 20 00 .X.MSWIN4.1... .
-d 280 2ff
xxxx:0280 01 27 0D 0A 49 6E 76 61-6C 69 64 20 73 79 73 74 .'..Invalid syst
xxxx:0290 65 6D 20 64 69 73 6B FF-0D 0A 44 69 73 6B 20 49 em disk...Disk I
xxxx:02A0 2F 4F 20 65 72 72 6F 72-FF 0D 0A 52 65 70 6C 61 /O error...Repla
xxxx:02B0 63 65 20 74 68 65 20 64-69 73 6B 2C 20 61 6E 64 ce the disk, and
xxxx:02C0 20 74 68 65 6E 20 70 72-65 73 73 20 61 6E 79 20 then press any
xxxx:02D0 6B 65 79 0D 0A 00 00 00-49 4F 20 20 20 20 20 20 key.....IO
xxxx:02E0 53 59 53 4D 53 44 4F 53-20 20 20 53 59 53 7E 01 SYSMSDOS SYS~.
xxxx:02F0 00 57 49 4E 42 4F 4F 54-20 53 59 53 00 00 55 AA .WINBOOT SYS..U.
-
-l 100 0 0 1 [ a floppy in the >A: drive. ]
-d 100 13d
xxxx:0100 EB 3C 90 29 47 38 71 33-49 48 43 00 02 01 01 00 .<.)G8q3IHC.....
xxxx:0110 02 E0 00 40 0B F0 09 00-12 00 02 00 00 00 00 00 ...@............
xxxx:0120 00 00 00 00 00 00 29 40-16 D8 13 4E 4F 20 4E 41 ......)@...NO NA
xxxx:0130 4D 45 20 20 20 20 46 41-54 31 32 20 20 20 ME FAT12
-
-l 100 0 0 1 [ a different floppy in the A: drive. ]
-d 100 13d
xxxx:0100 EB 3C 90 53 59 53 4C 49-4E 55 58 00 02 01 01 00 .<.SYSLINUX.....
xxxx:0110 02 E0 00 40 0B F0 09 00-12 00 02 00 00 00 00 00 ...@............
xxxx:0120 00 00 00 00 00 00 29 7E-CF 55 3C 20 20 20 20 20 ......)~.U<
xxxx:0130 20 20 20 20 20 20 46 41-54 31 32 20 20 20 FAT12
-
-d 2d0 2ff
xxxx:02D0 42 3B 16 1A 7C 72 03 40-31 D2 29 F1 EB A7 42 6F B;..|r.@1.)...Bo
xxxx:02E0 6F 74 20 66 61 69 6C 65-64 0D 0A 00 00 00 00 4C ot failed......L
xxxx:02F0 44 4C 49 4E 55 58 20 53-59 53 F4 3C 82 3A 55 AA DLINUX SYS.<.:U.
Note that the Linux Boot disk above (note the word: SYSLINUX) is the kind formatted as an MS-DOS diskette and not with a true Linux file system (such as ext2 or ext3). If it had been formatted with some other kind of file system, or had a faulty boot sector, then MS-DEBUG would not be able to read it! Instead you'd see that old "General failure reading drive A / Abort, Retry, Fail?" error message! And when you had finally cleared away that error message, you'd be greeted by DEBUG's "Disk error reading drive A" error message. This makes DEBUG almost worthless as far as trying to fix an error in a floppy disk's boot sector! However, if you keep a binary copy of a good floppy disk Boot Sector somewhere, you could use DEBUG to overwrite whatever's on a faulty floppy disk's first sector (see Write command). But if you really want to see what's in such a Boot sector (that keeps DEBUG from recognizing it as valid), you'll need to use a disk editor such as Symantec's Norton DiskEdit (in Physical disk Mode only).
NOTE: Just because a floppy disk can't be
read by DOS or opened in DEBUG does NOT necessarily mean it's defective. It
might simply have been formatted with a file system it cannot recognize (such
as Linux's ext2) and could easily boot-up on its own; this is a very
good reason for labeling your disks! (CAUTION: Never try booting your system
with a disk you're not 100% sure of; unless you disconnect all hard disks and
don't have any flash BIOS, since it might contain a nasty boot virus!
)
[ Many floppy disks have the letters IHC
in their OEM ID field. What kind of OEM Name is that? None. Someone at
Microsoft decided that this was where they'd place a new pseudo-random type
of identification to make sure that any information cached by 'Windows 9x'
from one disk wouldn't be mixed up with info from a different one if you swapped
disks. The whole string begins with five pseudo-random hex bytes,
and always ends with the characters IHC. All floppy diskettes
that are not write-protected will have any original OEM ID overwritten.
Once Windows has written this string, it will remain the same for any future
disk reads or writes. However, performing even a quick format under Windows,
will change the five hex bytes every time.
Some have concluded that the characters 'IHC' are the first
three letters of the word "Chicago" in reverse order, since
Chicago was the 'code name' for Windows 95™ before it was
ever released (it would have appeared as ' OGACIHC' on the hypothetical disk).
Although certainly a possibility, I have no proof of that. Due to my interest
in some very old Greek Manuscripts, I still can't help seeing the 3 characters
'IHC' as an Iota, Eta and old style Sigma since this combination of letters
was often used as an abbreviation for the Greek word IHSUS. Just another one
of those coincidences of life.
REMEMBER: If you really want to preserve all of the contents
of an important diskette, you can't even perform a simple Directory read under
a Windows OS, UNLESS it is 'write-protected' and you know the
drive's write-protect system is functioning correctly! ]
Back to TOCThis command should really be called: COPY (not Move) as it actually copies all the bytes from within the specified range to a new address.
Move: M range address
1) -m 7c00 7cff 600Copies all the bytes between Offset 7C00 and 7CFF (inclusive) to Offset 0600 and following...
2) -m 100 2ff 70This second example shows that it's very easy to overwrite most of the source you're copying from using the Move command. Apparently, DEBUG stores the source bytes elsewhere before writing them; otherwise, this example would cause a problem when it started overwriting what it hadn't copied yet! This copies the 512 bytes between Offsets 100h and 2FFh (inclusive) to Offset 0070 overwriting the first 368 bytes in the process.
Back to TOC
Name: N [pathname] [arglist]
This command can be used to load
files into DEBUG's Memory after you have started the program, but it's
main function is to create a new file under control of the Operating System
which DEBUG can WRITE data to.
Normally, when you want to 'debug' a file, you'd start DEBUG with
a command like this: C:\WINDOWS>debug
test.com . But it's also possible to load a file into DEBUG's
Memory from within DEBUG itself by using the 'N' command and then the
'L' command (with no parameters) like
this:
-n c:\temp\test.com
-l
which will load the file test.com into DEBUG's Memory starting at location CS:0100
(you cannot specify any other location when using the L command like
this!).
The 'N' command makes it quite easy
to save data or an Assembly program created in DEBUG to a file on your hard
drive!
For example, these commands (in bold; along with DEBUG's reponses):
will create a 68-byte file called DOSWINOK.COM in the C:\TEMP folder; even when running DEBUG in a DOS-window. The file names, however, are still limited to DOS's eight characters plus three for the extension (an 8.3 filename as it's often called)!
Note: Unlike the other programs listed on this page, this one uses Function 4Ch instead of Function 00 of Interrupt 21h to terminate its execution. This is the preferred termination function for most DOS programs, because it can not only send a "Return Code" (an ERRORLEVEL value; of whatever is in the AL register), but will also close all open files and free all memory belonging to the process. When you use this function to terminate a program running under DEBUG though, it has a tendency to also terminate DEBUG itself; thus our reason for rarely using it here!
Homework: Follow the steps above to Assemble and save this program under DEBUG, then use DEBUG to debug it! Use the P(roceed) command to step through most of the instructions, since this will keep you from accidentally stepping into an INT(errupt) instruction! If you ever do use the T(race) command on an INT, you'll end up inside nests of BIOS routines which often crashes DEBUG!
Back to TOCEntering ' r ' all by itself will display all of the 8086 register's contents and the next instruction which the IP register points to in both machine code and an unassembled (Assembly Language) form. For example, if you start DEBUG in a Windows 95B DOS-box with the command line:
Register: R [register]
AX=0000 BX=0000 CX=1437 DX=0000 SP=FFFE BP=0000 SI=0000 DI=0000 DS=0ED8 ES=0ED8 SS=0ED8 CS=0ED8 IP=0100 NV UP EI PL NZ NA PO NC 0ED8:0100 E90E01 JMP 0211For an explanation of the names of the registers (AX, BX, CX, etc. and the Flag symbols: NV UP EI PL NZ NA PO NC), see the Appendix (The 8086 CPU Registers). The last line shows that the next CPU instruction (actually the first in this case) to be executed, begins at memory location 100 hex (the Offset) in Segment ED8 hex (0ED8:0100) and that the Hex bytes E90E01 represent the actual binary machine code of the CPU instruction (JMP 0211 in Assembly language) that would be executed by DEBUG if you entered a Trace (t) or Proceed (p) command.
Back to TOCThe T command is used to trace (step through) CPU instructions one at a time. If you enter the T command all by itself, it will step through only ONE instruction beginning at the location specified by your CS:IP registers, halt program execution and then display all the CPU registers plus an unassembled version of the next instruction to be executed; this is the 'default' mode of the TRACE command. Say, however, you wanted DEBUG to trace and execute seven instructions beginning at address CS:0205; to do so, you would enter:
Trace: T [=address] [number]
Back to TOCProceed acts exactly the same as Debug's T (Trace) command for most types of instructions... EXCEPT: Proceed will immediately execute ALL the instructions (rather than stepping through each one) inside any Subroutine CALL, a LOOP, a REPeated string instruction or any software INTerrupts. This means that you do not have to single-step through any of the code contained in a Subroutine or INT call if you use the Proceed (P) command.
Proceed: P [=address] [number]
Back to TOC
Write: W [address] [drive] [firstsector] [number]
|
-n mymbr.bin -rcx CX 0001 :200 -w 0 Writing 00200 bytes [ 512 bytes in decimal ] -
The BX register had
already been set to zero by a previous instruction, so the CX register was simply
set to 200 and the WRITE command executed with an address of 0 (if no
address is used, the Write command starts saving bytes at Offset 100).
The WRITE command can, however, be used in a relatively safe manner
with Floppy disks. For example, you could use the Load (L) command:
l 7c00 0 0 1
to load the first sector of an MS-DOS or Windows floppy disk into DEBUG's memory
at location 7C00, change some of the code and/or messages (if you know how to
do so) and then use the 'W' command:
w 7c00 0 0 1
to write the changes back to the floppy disk's first sector.
___________________
*Although
the BX and CX registers are often referenced in books on Assembly as BX:CX
when they discuss the write command, NOTE that these registers
are not being used like Segment:Offset pairs in this case! They are a
true combination of higher and lower bytes which form a 'double word' for a
theoretical total of four Gigabytes (FFFF FFFFh
= 4,294,967,295 bytes) that could be written to a file! I'm not sure if this
has always been true of DEBUG, but under DOS 7.1 (sometimes called Windows 98),
I've been able to load image files of several hundreds of KB and then write
the whole file to a new location!
For example, if I load a 360 KB image file into DEBUG at
a DOS prompt, then check the registers, BX
will equal 0005 and CX will
contain A000. The major problem here though
is the fact that DEBUG uses CONVENTIONAL MEMORY, so trying to load an
image file greater than about 400KB or so is bound to elicit an "Insufficient
Memory" error!
[ click here to go back to text above
]
Back to TOC
|