About me

Course Work




Using Turbo Debugger

As Dr. Lovell said in class, we will not be covering the Turbo Debugger in class. However, I recognize that many of you will want to use this tool, so I will give you a few quick instructions on how to use it. Please understand that you should not spend too much time learning how to use this tool. We will very quickly advance to programs where using a dubugger is impossible. You will be much better off learning how to read through code and debug it on paper. This will be made easier if you spend your time designing on paper. The best time to use the debugger is when you suspect that you are trashing your stack (I'll cover this in class) or when you are trying to figure out what some interrupt call is doing - sometimes they change registers and are NOT documented well!

Given that, where do we begin. Grab the hi_world.asm file I provided as an example and compile it using the al.bat file also provided. As you probably noticed, this batch file tells the assembler and linker to retain all of the debugging information. To launch the debugger type td hi_world which will launch the debugger and load the program.


When the debugger first starts up, you will be presented with a blue screen and will see a copy of your source code. This view is only available if you have compiled your code and retained all of the debugging information. The CPU view will be the default if you are missing any of the debugging info. In this code view, you can move up and down with the arrow keys. The current instruction is denoted by an arrow in the left-hand margin. This will move as you step or trace through the program. If you want to set a breakpoint like you would in C, simply move to that line and press F2 to toggle a breakpoint on or off. TurboDebug will highlight that line in red. To execute your code up to that break point, press F5.

Step Over vs. Trace Through

To execute your program line by line, you have two choices. Stepping over (F8) will execute entire procedures (calls) or interrupts and break on the next line. Tracing into (F7) will enter a procedures or interrupt and allow you execute each line individually. The former is useful when you have many routines that you know work, and you don't want to waste time watching each line execute. The latter is useful when you are trying to debug a procedure that may be causing a side-effect and screwing up other routines. You will get a feel for when to do which very quickly if you start to work with this utility.


If you pull down the view menu, you will see a variety of windows that you can open. The most useful window is the CPU view. It is also the most confusing. On the right-hand side you will see a list of all of your registers. The value currently stored in each register is shown, and will change as you step or trace through your program. Just to the right of that, you will see the flags listed with their boolean value. They are carry, zero, sign, overflow, parity, auxiliary, interrupt, and direction respectively. If you look to the large section on the left-hand side, you will see
cs:000E B80452 mov ax, _DATA
which is the first instruction in the hi_world program. The arrow between the offset (000E) and the instruction (B80452) indicates the current instruction. Below, in the bottom-left view port is the data segment. Actually, if you look at DS, it is probably the same as ES which is NOT where our data is. If you step through the first few lines of the program you will initialize the DS register. Once you have done that, right-click in the data segment window, select GOTO and type in ds:0000. You should see your data Hello World in there. The last portion of the CPU view is the stack. Notice that the stack builds from the top down. We declared the stack to be 100h words, but SP=C8h. This is because a portion of the stack is in use. You can look through it using the view port in the bottom-right corner.

Of course, you don't have to have all of these view ports in one window. Turbo Debugger does have the option of opening any one or more of these windows separately. Don't waste a lot of time with this, just use the little bit you need and get back to designing your code more carefully.

Okay, so you now have a little background with the debugger. Allow me to interject a small personal comment. If you find a bug in your program, and reading through a printout of your code doesn't find it. I would strongly recommend taking out the portion of code that is not working, put it in a separate module, and force all of the registers to be what you expect them to be when you enter that block of code. When you get it working, you will hopefully have identified your bugs and fixed them. More times than not, you will do this exercise and then find that the code you thought was broken... works fine. The reason for a bug typically is a trashing of the stack or a slight typo (DS and DX look really similar after an hour of coding, trust me). The debugger will not catch or even help identify errors like this. Careful reading of your code will be the only way. Use your classmates to have them look over sections you are stuck with due to a bug, don't copy code, but feel free to help spot typos, etc.

Last Modified: January 26, 1999 - Barry E. Mapen