How to use DOS debug program for
assembly language programming
2009 September 24
tags: Assembly Language Programming, Computing, Hardware and Assembly Language
by Biswajit
The DOS debug program is a useful tool for writing and debugging assembly
programs. To start debug program, go to Start>Run. Then type cmd and hit Enter. This
will open the command prompt window. Here type “debug” and hit Enter. This will
invoke the DOS debug program and the prompt will change itself into a hyphen “-”.
To Start working with debug, lets first explore its help option. Type “?” in the debug
prompt and hit enter. This will show the following things,
-?
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
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
register R [register]
search S range list
trace T [=address] [value]
unassemble U [range]
write W [address] [drive] [firstsector] [number]
allocate expanded memory XA [#pages]
deallocate expanded memory XD [handle]
map expanded memory pages XM [Lpage] [Ppage] [handle]
display expanded memory status XS
-
Lets see what we need to enter and run an assembly language program through this
program. There are two ways to enter codes into memory, either by using -e command or
by using -a command. Lets first demonstrate the -e command. We can enter values by
using -e address command where [address] is the offset of the location in the segment
where we want to enter the value.
-e 100
3000:0100 00.32
Here no segment is specified so the -e command selects default segment DS. To enter
data in different segment locations we may use the following with the -e command. We
want to enter the value 45h in location CS:0120 so we use this modification.
-e cs:120
448A:0120 00.45
There is yet another way to input a string with the -e command. Take a look at the
following example. Here we’ve only specified the starting address in data segment from
where the string “Hello World” is to be stored. Then we use a -d command. This
command is used to dump the hexadecimal contents of a range of memory locations.
-e ds:100 “Hello World”
-d ds:100
13F2:0100 48 65 6C 6C 6F 20 57 6F-72 6C 64 00 00 00 00 00 Hello World…..
13F2:0110 00 00 00 00 00 00 00 00-00 00 00 00 34 00 E1 13 …………4…
13F2:0120 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 …………….
13F2:0130 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 …………….
13F2:0140 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 …………….
13F2:0150 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 …………….
13F2:0160 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 …………….
13F2:0170 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 …………….
-
The syntax of -d or dump command is -d or, -d address, or -d range. Now if no address is
given the -d command will dump the address from where tha last used -d command left
off. Lets see the following demonstration. We put a string starting from location DS:100
and then use the -d command which dumps location DS:100 through DS:17F.
-e 100 “Hello Welcome to Assembly Language Programming through Debug”
-d 100
3000:0100 48 65 6C 6C 6F 20 57 65-6C 63 6F 6D 65 20 74 6F Hello Welcome to
3000:0110 20 41 73 73 65 6D 62 6C-79 20 4C 61 6E 67 75 61 Assembly Langua
3000:0120 67 65 20 50 72 6F 67 72-61 6D 6D 69 6E 67 20 74 ge Programming t
3000:0130 68 72 6F 75 67 68 20 44-65 62 75 67 00 00 00 00 hrough Debug….
3000:0140 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 …………….
3000:0150 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 …………….
3000:0160 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 …………….
3000:0170 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 …………….
Now again we enter another string starting from where we left i.e. DS:180. Now we again
use the -d command which dumps DS:180 to DS:1FF.
-e 180 “The next -d command should show this content”
-d
3000:0180 54 68 65 20 6E 65 78 74-20 2D 64 20 63 6F 6D 6D The next -d comm
3000:0190 61 6E 64 20 73 68 6F 75-6C 64 20 73 68 6F 77 20 and should show
3000:01A0 74 68 69 73 20 63 6F 6E-74 65 6E 74 00 00 00 00 this content….
3000:01B0 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 …………….
3000:01C0 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 …………….
3000:01D0 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 …………….
3000:01E0 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 …………….
3000:01F0 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 …………….
-
One can also specify the range of addresses that has to be dumped. Take a look at the
following -d command where we’ve asked for only a specified range of addresses to
dump viz ES:100 through ES:120
-e es:100 “This string is in Extra Segment”
-d es:100 120
8000:0100 54 68 69 73 20 73 74 72-69 6E 67 20 69 73 20 69 This string is i
8000:0110 6E 20 45 78 74 72 61 20-53 65 67 6D 65 6E 74 00 n Extra Segment.
8000:0120 00 .
-
Now that we’ve learned -e and -d command quite successfully, we will focus to probably
the most important command in debug which is the -a command. The syntax is -a
[address] where the [address] is the offset of a particular segment of memory. If [address]
is omitted the program will start assembling from current location in Code Segment. By
default -a command starts assembling in the Code Segment. To terminate inputting
instructions just press another Enter.
-a
13F2:0100 MOV AX,09
13F2:0103
-
The default location here is 13F2h which is the starting location for CS. Now lets
mention the offset along with the -a command.
-A 120
13F2:0120 MOV AX,09
13F2:0123
-
Now I will change the default location by explicitely specifying the segment. Here we
want to assemble in data segment; so we’ve used
-a DS:120.
-a ds:120
3000:0120 MOV AX,09
3000:0123
-
Now lets try to write a program with -a command. Here we want to print the character
‘A’ so we start entering the instructions from offset 100 of Code Segment. After we’ve
finished entering all instructions we press Enter to get outta -a command scope.
-A 100
448A:0100 MOV AH,02
448A:0102 MOV DL,41
448A:0104 INT 21
448A:0106
-
Now that all the required instructions have been entered we would like to execute them.
We can do it either by a -g command or by -p command. But before executing these
instruction we have to ensure that the content of IP is the location of the starting address
of the program. Here the starting address of the program we’ve written is CS:0100. So we
use the -r command to set the IP to this value.
-R IP
IP 0106
:100
-G 106
A
AX=0241 BX=0000 CX=0000 DX=0041 SP=FFEE BP=0000 SI=0000 DI=0000
DS=3000 ES=8000 SS=6000 CS=448A IP=0106 NV UP EI PL NZ NA PO NC
448A:0106 0000 ADD [BX+SI],AL DS:0000=00
-
The syntax of the -g command is -g breakpoint, or -g [starting address] breakpoint, or -g
[starting address] breakpoint1 breakpoint2 …Here in this program we’ve used -g 106
which means execution will “go until” the location CS:0100. Execution will start from
the location indicated by IP, where we’ve entered the location offset 0100 and it will stop
until it reaches 0106.
Now in this program we’ve entered 02h in AH. This along with the combination of INT
21h serves a function DOS function call that prints the character represented by the
ASCII value stored in DL. The number 41h, which is the ASCII for character “A” is
moved into DL. After executing the program an “A” is printed on CRT.
Now lets take a deeper look into the -r command we’ve used in above example. While
this command is used along with any of the registers it will first show the content of that
register and then ask for a new value. You can enter a new value or just skip it by another
Enter.
-R ES
ES 13F2
:8000
-R SS
SS 13F2
:6000
-R CS
CS 13F2
:448A
-R DS
DS 13F2
:3000
An -r command without specifying any register will just show the contents of all registers
including the status of the flag register.
-R
AX=0000 BX=0000 CX=0000 DX=0000 SP=FFEE BP=0000 SI=0000 DI=0000
DS=3000 ES=8000 SS=6000 CS=448A IP=0100 NV UP EI PL NZ NA PO NC
448A:0100 0000 ADD [BX+SI],AL DS:0000=00
-
Executing can be done in a rather extensive way, in a step by step process by the -p or
proceed command. The syntax of this command is -p for a single step execution. -p
[address] executes a single instruction at offset location [address] and -p [address] n
executes the n number of instruction starting from offset location [address]. We start
using the -p command for the program we’ve already used.
-R IP
IP 0106
:100
-P
AX=0200 BX=0000 CX=0000 DX=0041 SP=FFE6 BP=0000 SI=0000 DI=0000
DS=3000 ES=8000 SS=6000 CS=0332 IP=0102 NV UP DI PL ZR NA PE CY
0332:0102 B241 MOV DL,41
-P
AX=0200 BX=0000 CX=0000 DX=0041 SP=FFE6 BP=0000 SI=0000 DI=0000
DS=3000 ES=8000 SS=6000 CS=0332 IP=0104 NV UP DI PL ZR NA PE CY
0332:0104 CD21 INT 21
-P
A
AX=0241 BX=0000 CX=0000 DX=0041 SP=FFE6 BP=0000 SI=0000 DI=0000
DS=3000 ES=8000 SS=6000 CS=0332 IP=0106 NV UP DI PL ZR NA PE CY
0332:0106 4B DEC BX
As the INT 21h instruction is executed the character “A” is shown on the screen. Also
with each -p or a -g command the content of all the registers are shown.
There is another very useful command -u or unassemble. This command shows a
dissassembly of the instructions from the offset location specified. If no address is
specified -u command will start dissassembling right from where the previous -u
command left off.
-u cs:100
0332:0100 B402 MOV AH,02
0332:0102 B241 MOV DL,41
0332:0104 CD21 INT 21
0332:0106 4B DEC BX
0332:0107 53 PUSH BX
0332:0108 54 PUSH SP
0332:0109 41 INC CX
0332:010A 43 INC BX
0332:010B 4B DEC BX
0332:010C 53 PUSH BX
0332:010D 54 PUSH SP
0332:010E 41 INC CX
0332:010F 43 INC BX
0332:0110 4B DEC BX
0332:0111 53 PUSH BX
0332:0112 54 PUSH SP
0332:0113 41 INC CX
0332:0114 43 INC BX
0332:0115 4B DEC BX
0332:0116 53 PUSH BX
0332:0117 54 PUSH SP
0332:0118 41 INC CX
0332:0119 43 INC BX
0332:011A 4B DEC BX
0332:011B 53 PUSH BX
0332:011C 54 PUSH SP
0332:011D 41 INC CX
0332:011E 43 INC BX
0332:011F 4B DEC BX
-
To specify a certain range of addresses to dissassemble the command is -u [starting
address] [ending address].
-u cs:100 108
0332:0100 B402 MOV AH,02
0332:0102 B241 MOV DL,41
0332:0104 CD21 INT 21
0332:0106 4B DEC BX
0332:0107 53 PUSH BX
0332:0108 54 PUSH SP
-
I’ve so far discussed only the most essential debug commands as this article is only about
how to use the debug utility for assembly language programs. There are many
documentations and tutorials for the debug program itself and they are available online
for free. As this program is available to almost all users it is, unlike other third party
assemblers and emulator softwares, the easiest way to do your assembly language
programs. The debug utility, as I personally think is very useful for beginners in assembly
language programming.
Related Posts on this Site
The 8086 microprocessor
The 8086 microprocessor Instruction Set Quick Reference
Tools required for Assembly Language Programming
How to use Emu8086 for Assembly Language Programming
Your very first Program in Assembly Language
Ads by Google
SQR Debugger
Save time in coding and testing! GUI-based, easy to use. Free trial.
www.sparkpath.com
from → Computing, Hardware and Architecture, x 86 Assembly Language Programming
5 Responses leave one →
Trackbacks & Pingbacks
1. Tools Required for Assembly Language Programming « self-learner's blog
2. Your very first program in Assembly Language « self-learner's blog
3. How to use Emu8086 for assembly language programming « self-learner's blog
4. Calculating the average of 3 given numbers « A Self-Learner's Blog
5. A program for String Concatenation « A Self-Learner's Blog