`
`Debugging Tools and Techniques
`
`MS-DOS provides a wide variety of tools to aid in the debugging process. Some are
`intended specifically for debugging. For example, the DEBUG program is delivered with
`MS-DOS and provides basic debugging aid; the more sophisticated SYMDEB is supplied
`with MASM, Microsoft's macro assembler; Code View, a debugger for high-order languages,
`is supplied with Microsoft C, Microsoft Pascal, and Microsoft FORTRAN. Others are gen(cid:173)
`eral MS-DOS services and features that are also useful in the debugging process.
`
`Debugging, like programming, has aspects of both an art and a craft. The craft- the
`mechanical details of using the tools- is discussed both here and elsewhere in this
`volume, but the main subject of this article is the art of debugging- the choice of the
`correct tool, the best techniques to use in various situations, the methods of extracting the
`clues to the problem from a recalcitrant program.
`
`Debugging a program is a form of puzzle solving. As with most intellectual detective
`work, the following rule applies:
`
`Gather enough information and the solution will be obvious.
`
`The craft of debugging involves gathering the data; the art lies in deciding which data to
`gather and in noticing when the solution has become obvious.
`
`The methods of gathering data for debugging, listed in order of increasing difficulty and
`tediousness, fall into four major categories:
`
`Inspection and observation
`•
`Instrumentation
`•
`• Use of software debugging monitors (DEBUG, SYMDEB, and Code View)
`• Use of hardware debugging aids
`
`As mentioned above, part of the art of debugging is knowing which method to use. This
`is one of the most difficult aspects of debugging-so difficult, in fact, that even program(cid:173)
`mers with years of experience make mistakes. Many programmers have spent hours
`single-stepping through a program with DEBUG only to discover that the cause of the
`problem would have been obvious if they had given the program's output even a cursory
`check. The only universal rule for choosing the correct debugging method is
`
`Try them all, starting with the simplest.
`Inspection and observation
`Inspection and observation is the oldest and, usually, the best method of program debug(cid:173)
`ging. It is also the basis for all the other methods. The first step with this method, as with
`the others, is to gather all the pertinent materials. Program listings, file layouts, report
`layouts, and program design materials (such as algorithm descriptions and flowcharts)
`are all extremely valuable in the debugging process.
`
`546
`
`The MS-DOS Encyclopedia
`
`ZTE (USA) 1007, Page 556
`
`
`
`l
`I
`
`Desk-checking
`
`Article 18: Debugging in the MS-DOS Environment
`
`Before a programmer can determine what a program is doing wrong, he or she must
`know the correct operation of the program. There was a time, when computers were rare
`and expensive resources, that programmers were encouraged not to run their programs
`until the programs had been thoroughly desk-checked. The desk-checking process in(cid:173)
`volves sitting down with a listing, a hand calculator, and some sample data. The program(cid:173)
`mer then "plays computer," executing each line of the program manually and writing
`down on paper the results of each program step. This process is extremely slow and
`tedious. When the desk-checking is completed, however, the programmer not only has
`found most of the bugs in the program but also has become intimately familiar with the
`execution of the program and the values of the program variables at each step.
`
`The advent of inexpensive yet powerful personal computers, combined with the rising
`cost of programmer time, has made complete desk-checking nearly obsolete. It is now
`cheaper to run the program and let the computer find the errors. However, the usefulness
`of the desk-checking technique remains. Many programmers find it helpful to manually
`execute those sections of a program that they suspect are causing trouble. Even if they
`don't find errors in the code, the insight they gain into the workings of the code and the
`values of the variables at each step can be invaluable when applying other debugging
`techniques.
`
`The inspection-and-observation methodology
`
`going astray. As the program executes, note whether each section performs correctly. 4
`
`The basic technique of the inspection-and-observation method is simple: After gathering
`all the required materials, run the program and observe. Observe very carefully; events
`that seem insignificant may be the very clues needed to discover where the program is
`
`Does the program clear the screen when it should? Does it ask for input when it should?
`Does it produce the correct results? Observable events are the debugger's milestones in
`the execution of the program. If the program clears the screen but writes purple asterisks
`instead of requesting input, then the problem lies somewhere after the program issues the
`Clear Screen command but before it writes the input prompt on the screen. At this point,
`the program listing and design data become important. Inspect the listing and examine
`the area after the last successful milestone and before the missing milestone. Look for a
`logic error in the code that could explain the observed data.
`
`If the program produces printed reports, they may also be useful. Watch the screen and
`listen to the printer. Clues can sometimes be found in the order in which things happen.
`The light on the disk drive can be another indication of activity. See how disk activity co(cid:173)
`ordinates with screen and printer events. Try to identify each section of the program from
`these clues. Then use this information to localize the inspection of the listing to isolate
`the erroneous code.
`
`The values of data given in reports and on the screen can also give clues to what's going
`wrong. Examining the data and reconstructing the values used to compute it sometimes
`leads to inferences about data problems. Perhaps a variable was misspelled in the code
`
`Section 11· Programming in the MS-DOS Environment
`
`547
`
`ZTE (USA) 1007, Page 557
`
`
`
`Part E: Programming Tools
`
`or perhaps a data file is in the wrong format or has been corrupted. With this information,
`the bug can often be isolated. However, a very thorough knowledge of the program and its
`algorithms is required. See Desk-checking above.
`
`MS-DOS provides four commands and filters that are useful in the collection and examina(cid:173)
`tion of data for debugging: TYPE, PRINT, FIND, and DEBUG. All these commands display
`the data in a file in some way. If the data is ASCII (displayable) characters, TYPE and
`PRINT can be used, with some help from FIND. Binary files can be examined and modi(cid:173)
`fied with the DEBUG utility. See USER COMMANDS: FIND; PRINT; TYPE; PROGRAMMING
`UTILITIES: DEBUG.
`
`The TYPE command provides the simplest way to display ASCII data files. This method
`can be used to examine both input and output files. Checking the input files may uncover
`some bad (or unexpected) data that causes the program to malfunction; examining the
`output files will show whether calculations are being performed correctly and may help
`pinpoint the erroneous calculations if they are not.
`
`The FIND utility is useful in locating specific data in a file. Using FIND is more accurate
`and definitely less tedious than examining the file manually using the TYPE command.
`The IN switch causes FIND to also display the relative line number of the matching line(cid:173)
`information that is most useful in debugging.
`
`Sometimes the data is too complex to be examined on the screen and printed copy is
`needed. The PRINT command will produce hard copy of an ASCII file as will the TYPE
`command if its output is redirected to the printer with the >PRN command-line parameter
`after the filename.
`
`Not all data files contain pure ASCII data, and displaying such non-ASCII files requires a
`different approach. The TYPE command can be used, but nonprintable characters will
`produce garbage on the screen. This technique can still prove useful if the file has a large
`amount of ASCII data or if the records are regular and the ASCII information always
`appears at the same location, but no information can be gained about non-ASCII numeric
`data in such files. Note also that the entire file might not be displayed using TYPE because
`if TYPE encounters a byte containing lAH (Control-Z), it assumes it has reached the end
`of the file and stops.
`
`Clearly, a more useful tool for examining non-ASCII files would be a program that dumps
`the file in hexadecimal, with an appropriate translation of all·displayable characters. Such
`programs exist in the public domain (through bulletin-board services, for instance) and, in
`any event, are not difficult to write. MS-DOS does not include a stand-alone file-dumping
`program among its standard commands and utilities, but the DEBUG program can be
`used, with minor inconvenience, to display files. This program is discussed in detail later
`in this article; for now, simply follow these instructions to use DEBUG as a file dumper.
`To load DEBUG and the program to be debugged, use the form
`
`DEBUG [drive:] [path]jilename.ext
`
`DEBUG will display a hyphen as a prompt. To see the contents of the file, enter D (the
`DEBUG Display Memory command) and press Enter. DEBUG will display the first 128
`(80H) bytes of the file in hexadecimal and will also show any displayable characters.
`
`548
`
`The MS-DOS Encyclopedia
`
`ZTE (USA) 1007, Page 558
`
`
`
`&tide 18: Debugging in the MS-DOS Environment
`
`To see the rest of the file, simply continue entering D until the desired area is found. Hard
`copy of the contents of the display can be made by using the PrtSc key (or Ctrl-PrtSc to
`print continuously). Note that the offset addresses for the bytes in the file begin at the
`value in the program's CS:IP registers, which can be viewed by using the Debug R (Display
`or Modify Registers) command. To obtain the true offsets, subtract CS:IP from the address
`shown.
`
`The essence of the inspection-and-observation method is careful and thoughtful observa(cid:173)
`tion. The computer and the operating system can provide tools to aid in the collection of
`data, but the most important tool is the programmer's mind. By applying the logical skills
`they already possess to the observed data, programmers can usually avoid the more
`complex forms of debugging.
`Instrumentation
`Debugging by instrumentation is a traditional method that has been popular since pro(cid:173)
`grams were holes punched in cards. In general, this method consists of adding something
`to the program, either internally or externally, to report on the progress of program execu(cid:173)
`tion. Programmers call this added mechanism instrumentation because of its resemblance
`to the measuring instruments used in science and engineering. Instrumentation can be
`software, hardware, or a combination of both; it can be internal to the program or external
`to it. Internal instrumentation is always software, but external instrumentation may be
`either hardware or software.
`
`Internal instrumentation
`
`Internal instrumentation usually consists of display or print statements placed at strategic
`
`locations. Other signals to the user can be used if they are available. For instance, the sys- 4
`
`tern beeper can be sounded at key locations, perhaps in a coded sequence of beeps; if the
`device being debugged has lights that can be accessed by the program, these lights can be
`flashed at important locations in the program. Beeping and flashing do not, however,
`possess the information content usually required for debugging, so display or print state-
`ments are preferred.
`
`The use of display or print statements to display key data and milestones on the screen or
`printer requires careful planning. First, apply the techniques of inspection and observation
`described in the previous section to determine the most probable points of failure. Then, if
`there is some doubt about what path execution is taking through the code, embed mes(cid:173)
`sages of the following types after key decision points:
`
`BEGINNING SORT PHASE
`ENDING PRINCIPAL CALCULATION
`PROCESSING RECORD XX
`
`A second way to use display or print statement instrumentation is to embed statements that
`display the data and interim values used for calculations. This technique can be extremely
`useful in finding problems related to the data being processed. Consider the QuickBASIC
`program in Figure 18-1 as an example. The program has no syntax errors and compiles
`cleanly, but it sometimes produces an incorrect answer.
`
`Section /1- Programming in the MS-DOS Environment
`
`549
`
`/
`
`ZTE (USA) 1007, Page 559
`
`
`
`Part E: Programming Tools
`
`EXP.BAS -- COMPUTE EXPONENTIAL WITH INFINITE SERIES
`
`X
`
`EXP(x)
`
`1 +
`
`+
`
`+
`
`+
`
`+ ...
`
`I **********************************************************************
`' *
`*
`' * EXP
`*
`' *
`*
`' * This routine computes EXP(x) using the following infinite series: *
`' *
`*
`' *
`' *
`' *
`*
`' *
`*
`' *
`' * The program requests a value for x and a value for the convergence *·
`' * criterion, C. The program will continue evaluating the terms of
`*
`*
`' *
`the series until the difference between two terms is less than C.
`*
`' *
`' * The result of the calculation and the number of terms required to *
`' * converge are printed. The program will repeat until an x of 0 is *
`' * entered.
`*
`' *
`*
`I **********************************************************************
`
`*
`
`1!
`
`2!
`
`3!
`
`4!
`
`5!
`
`Initialize program variables
`
`INITIALIZE:
`TERMS = 1
`FACT =
`LAST= 1.E35
`DELTA = 1 .E34
`EX = 1
`
`Input user data
`
`INPUT "Enter number:
`IF X = 0 THEN END
`INPUT "Enter convergence criterion (.0001 for 4 places)
`
`"; X
`
`"; c
`
`Compute exponential until difference of last 2 terms is < C
`
`WHILE ABS(LAST- DELTA) >= C
`LAST = DELTA
`FACT = FACT * TERMS
`DELTA = XATERMS
`/ FACT
`EX = EX + DELTA
`TERMS +
`TERMS
`WEND
`
`Figure 18-1. A routine to compute exponentials.
`
`(more)
`
`550
`
`The MS-DOS Encyclopedia
`
`ZTE (USA) 1007, Page 560
`
`
`
`.Article 18: Debugging in the MS-DOS Environment
`
`·, Display answer and number of terms required to converge
`
`PRINT EX
`PRINT TERMS; "elements required to converge"
`
`GOTO INITIALIZE
`
`Figure 18-1. Continued.
`
`The purpose of the EXP.BAS program is to compute the exponential of a given number
`to a specified precision using an infinite series. The program computes the value of each
`term in the infinite series and adds it to a running total. To keep from executing forever,
`the program checks the difference between the last two elements computed and stops
`when this difference is less than the convergence criterion entered by the user.
`
`When the program is run for several values, the following results are observed:
`
`? 1
`Enter number:
`Enter convergence criterion (.0001 for 4 places):
`2.718282
`10 elements required to converge
`
`?
`
`.0001
`
`? 1.5
`Enter number:
`Enter convergence criterion (.0001 for 4 places):
`4.481686
`11 elements required to converge
`
`?
`
`.0001
`
`? 2
`Enter number:
`Enter convergence criterion (.0001 for 4 places):
`5
`3 elements required to converge
`
`? 2.5
`Enter number:
`Enter convergence criterion (.0001 for 4 places):
`12.18249
`15 elements required to converge
`
`.0001
`
`.0001
`
`? 3
`Enter number:
`Enter convergence criterion (.0001 for 4 places):
`13
`4 elements required to converge
`
`?
`
`.0001
`
`Enter number:
`
`? 0
`
`Some of these numbers are incorrect. Table 18-2 shows the computed values and the
`correct values.
`
`Section !1- Programming in the MS-DOS Environment
`
`551
`
`ZTE (USA) 1007, Page 561
`
`
`
`Part E: Programming Tools
`
`Table 18-2. The Computed Values Generated by EXP.BAS and the Expected
`Values.
`
`X
`
`1.0
`1.5
`2.0
`2.5
`3.0
`
`Computed
`
`Correct
`
`2.718282
`4.481686
`5
`12.18249
`13
`
`2.718282
`4.481689
`7.389056
`12.18249
`20.08554
`
`Applying the methods from the first section of this article and observing the data quickly
`reveals a pattern. With the exception of 1, all whole numbers give incorrect results, but all
`numbers with fractions give results that are correct to the specified convergence criterion.
`Examination of the listing shows no obvious reason for this. The answer is there, but only
`an exceptionally intuitive numeric analyst would see it. Because no answer is obvious, the
`next step is to validate the only information available- that whole numbers produce er(cid:173)
`rors and fractional ones do not. Repeating the first experiment with 2 and a number
`very close to 2 yields the following results:
`
`? 1.999
`Enter number:
`Enter convergence criterion (.0001 for 4 places):
`7.38167
`13 elements required to converge
`
`?
`
`.0001
`
`? 2
`Enter number:
`Enter convergence criterion (.0001 for 4 places):
`5
`3 elements required to conve,rge
`
`?
`
`.0001
`
`Enter number:
`
`? 0
`
`The outcome is the same- repeating the experiment with a number as near to 2 as the
`convergence criterion permits (1.9999) produces the same result. The error is indeed
`caused by the fact that the number is an integer.
`
`Because no intuitive way can be found to solve the mystery by inspection, the program(cid:173)
`mer must turn to the next method in the hierarchy, instrumentation. The problem has
`something to do with the calculation of the terms of the series. Therefore, the section of
`the program that performs this calculation should be instrumented by placing PRINT
`statements inside the WHILE loop (Figure 18-2) to display all the intermediate values
`of the calculation.
`
`WHILE ABS(LAST- DELTA) >= C
`LAST = DELTA
`FACT = FACT * TERMS
`DELTA = X A TERMS
`/ FACT
`
`Figure 18-2. Instrumenting the WHILE loop.
`
`(more)
`
`552
`
`The MS-DOS Encyclopedia
`
`ZTE (USA) 1007, Page 562
`
`
`
`Article 18: Debugging in the MS-DOS Environment
`
`EX = EX + DELTA
`PRINT "TERMS="; TERMS; "EX="; EX; "FACT="; FACT; "DELTA="; DELTA;
`PRINT "LAST="; LAST
`TERMS = TERMS + 1
`
`WEND
`
`Figure 18-2. Continued.
`
`The print statements used in this WHILE loop are typical of the type used for instrumenta(cid:173)
`tion. The program makes no attempt at fancy formatting. The print statements simply
`identify each value with its variable name, allowing easy correlation of the data and the
`code in the listing. Repeating the experiment with 1.999 and 2 yields
`
`.0001
`
`? 1.999
`Enter number:
`Enter convergence criterion (.0001 for 4 places):
`?
`TERMS=
`EX= 2.999 FACT= 1 DELTA= 1.999 LAST= 1E+34
`TERMS.= 2 EX= 4. 997001 FACT= 2 DELTA= 1 . 998 LAST= 1 . 999
`TERMS= 3 EX=
`6.328335 FACT= 6 DELTA= 1.331334 LAST= 1.998
`TERMS= 4 EX=
`6.993669 FACT= 24 DELTA=
`.6653343 LAST= 1.331334
`TERMS= 5 EX=
`7.25967 FACT= 120 DELTA=
`.2660006 LAST=
`.6653343
`TERMS= 6 EX=
`7.348292 FACT= 720 DELTA= 8.862254E-02 LAST=
`.2660006
`TERMS= 7 EX=
`7.373601 FACT= 5040 DELTA= 2.530806E-02 LAST= 8.862254E-02
`TERMS= 8 EX=
`7.379924 FACT= 40320 DELTA= 6.323853E-03 LAST= 2.530806E-02
`TERMS= 9 EX= 7.381329 FACT= 362880 DELTA= 1 .404598E-03 LAST= 6.323853E-03
`TERMS= 10 EX= 7.3816T FACT= 3628800 DELTA= 2.807791E-04 LAST= 1 .404598E-03
`TERMS= 11 EX= 7.381661 FACT= 3.99168E+07 DELTA= 5.102522E-05 LAST= 2.807791E-04
`TERMS= 12 EX= 7.38167 FACT= 4.790016E+08 DELTA= 8.499951E-06 LAST= 5.102522E-05
`7.38167
`13 elements required to converge
`
`? 2
`Enter number:
`Enter convergence criterion (.0001 for 4 places):
`TERMS=
`EX= 3 FACT= 1 DELTA= 2 LAST= 1E+34
`TERMS= 2 EX= 5 FACT= 2 DELTA= 2 LAST= 2
`5
`3 elements required to converge
`
`?
`
`.0001
`
`Examination of the instrumentation printout for the two cases shows a drastically different
`pattern. The fractional number went through 13 iterations following the expected pattern;
`the whole number, however, quit on the third step. The loop is terminating prematurely.
`Why? Look at the values calculated for DELTA and LAST on the last complete step. They
`are the same, giving a difference of zero. Because this difference will always be less than
`the convergence criterion, the loop will always terminate early. A moment's reflection
`shows why. The numerator of the fraction for each term but the first in the infinite series is
`a power of the number entered; the denominator is a factorial, a product formed by multi(cid:173)
`plying successive integers. Because n! = n •(n-1)!, when an integer is raised to a power
`equal to itself and divided by the factorial of that integer the result will always be the same
`as the preceding term. That is what has happened here.
`
`Section Jl- Programming in the MS-DOS Environment.
`
`553
`
`ZTE (USA) 1007, Page 563
`
`
`
`Part E: Programming Tools
`
`Now that the cause of the problem is found, it must be fixed. How can this problem be
`prevented? In this case, the problem is caused by a logic error. The programmer misread
`(or miswrote!) the algorithm and assumed that the criterion for termination was that the
`difference between the last two terms be less than the specified value. This is incorrect.
`Actually, the termination criterion should be that the difference between the forming
`EXP(x) and the last term be less than the criterion. To simplify, the last term itself must be
`less than the value specified. The correct program listing, including the new WHILE loop,
`is shown in Figure 18-3.
`
`EXP.BAS -- COMPUTE EXPONENTIAL WITH INFINITE SERIES
`
`' * EXP
`
`' .
`' .
`
`I **********************************************************************
`*
`*
`*
`*
`*
`*
`*
`*
`
`EXP(x)
`
`1 +
`
`X
`
`1!
`
`+ --- + --- +
`2!
`3!
`
`*.
`
`' * This routine computes EXP(x) using the following infinite series:
`' *
`' *
`' *
`' *
`I *
`*
`' *
`' * The program requests a value for x and a value for the convergence *
`' * criterion, C. The program will continue evaluating the terms of
`*
`' *
`*
`the series until the amount added with a term is less than C.
`' *
`*
`' * The result of the calculation and the number of terms required to *
`' * converge are printed. The program will repeat until an x of 0 is
`' * entered.
`*
`' *
`*
`t **********************************************************************
`
`Initialize program variables
`
`INITIALIZE:
`TERMS = 1
`FACT = 1
`DELTA= 1.E35
`EX = 1
`
`Input user data
`
`INPUT "Enter number:
`IF X = 0 THEN END
`INPUT "Enter convergence criterion (.0001 for 4 places):
`
`"; X
`
`"; c
`
`Compute exponential until difference of last 2 terms is < C
`
`Figure 18-3. Corrected exponential calculation routine.
`
`(more)
`
`554
`
`The MS-DOS Encyclopedia
`
`ZTE (USA) 1007, Page 564
`
`
`
`l I
`
`Article 18: Debugging in the MS-DOS Environment
`
`WHILE DELTA > C
`FACT = FACT * TERMS
`DELTA = XATERMS
`/ FACT
`EX = EX + DELTA
`TERMS + 1
`TERMS
`WEND
`
`Display answer and number of terms required to converge
`
`PRINT EX
`PRINT TERMS; "elements required to converge"
`
`GOTO INITIALIZE
`
`Figure 18-3. Continued.
`
`The program now produces the correct results within the limits of the specified accuracy:
`
`? 1.999
`Enter number:
`Enter convergence criterion (.0001 for 4 places):
`7.381661
`12 elements required to converge
`
`?
`
`.0001
`
`? 2
`Enter number:
`Enter convergence criterion (.0001 for 4 places):
`7.389047
`12 elements required to converge
`
`?
`
`.0001
`
`Enter number:
`
`? 0
`
`This example illustrates how easy it is to use internal instrumentation in high-order lan(cid:173)
`guages. Because these languages usually have simple formatted output commands, they
`require very little work to instrument. When these output commands are not available,
`however, more work may be required. For instance, if the program being debugged is in
`assembly language, it is possible that the code required to format and print internal data
`will be longer than the program being debugged. For this reason, internal instrumentation
`is rarely used on small and moderate assembly programs. However, large assembly pro(cid:173)
`grams and systems often already have print formatting routines built into them; in these
`cases, internal instrumentation may be as easy as with high-order languages.
`·
`
`External instrumentation
`
`Sometimes it is difficult to use internal instrumentation with a program. If, for instance,
`the problem is timing related, adding print statements could cloud the problem or, worse
`yet, make it go away completely. This leaves the programmer in the frustrating position of
`having the problem only when the cause can't be seen and not having the problem when
`it can. A solution to this type of problem can sometimes be found by moving the instru(cid:173)
`mentation outside the program itself. There are two types of external instrumentation:
`hardware and software.
`
`Section 11· Programming in the MS-DOS Environment
`
`55 5
`
`ZTE (USA) 1007, Page 565
`
`
`
`Part E: Programming Tools
`
`Hardware instrumentation consists of whatever logic analyzers, oscilloscopes, meters,
`lights, bells, or gongs are appropriate to the hardware and software under test. Hardware
`instrumentation is difficult to set up and tedious to use. It is, therefore, usually reserved for
`those problems directly associated with hardware. Such problems often arise when new
`software is being run on new hardware and no one is quite sure where the bugs are.
`Because most programmers reading this book are developing software on tried-and-true
`personal computer hardware and because most of those programmers are unlikely to have
`a logic analyzer costing several thousand dollars, we will skip over the use of hardware
`instrumentation for software debugging. If a logic analyzer must be used, the programmer
`should remember that the debugging philosophy and techniques discussed in this article
`can still be applied effectively.
`
`MS-DOS provides a feature that is very useful in building external instrumentation soft(cid:173)
`ware: the TSR, or terminate-and-stay-resident routine. See PROGRAMMING IN THE MS(cid:173)
`DOS ENVIRONMENT: CusTOMIZING Ms-nos: Terminate-and-Stay-Resident Utilities. This
`feature of the operating system allows the programmer to build a monitoring routine that
`is, in essence, a part of the operating system and outside the application program. The TSR
`is loaded as a normal program, but instead of leaving the system when it is done, it remains
`intact in memory. The operating system provides no way to reexecute the program after it
`terminates, so most TSRs are interrupt driven.
`
`Because TSRs exist outside the application program, they can be used to build external
`instrumentation devices. This independence allows them to perform monitoring functions
`without disturbing the logic flow of the application program. The only areas where inter(cid:173)
`ference is likely are those where the TSR and the program must use common resources.
`These conflicts typically involve timing but can also involve other resources, such as 1/0
`devices, disk files, and MS-DOS resources, including environment space. Some of these
`problems are addressed in the next example.
`
`The TSR type of external instrumentation software can prove useful in analyzing serial
`communications. Such an instrumentation program monitors the serial communication
`line and records all data. To detect protocol or timing problems, the program tags the
`recorded data so that transmitted data can be differentiated from received data. Hardware
`devices exist that plug into the serial port and perform both the monitoring and tagging
`function, but they are expensive and not always handy. Fortunately, this inexpensive piece
`of software instrumentation will serve in many cases.
`
`Software interrupt calls are made with the INT instruction. Although their service routines
`must obey similar rules, these interrupts should not be confused with hardware interrupts
`caused by external hardware events. Software interrupts in MS-DOS are used by an appli(cid:173)
`cation program to communicate with the operating system and, by extension in IBM sys(cid:173)
`tems, with the ROM BIOS. For example, on IBM PCs and compatibles, application pro(cid:173)
`grams can use software Interrupt 14H to communicate with the ROM BIOS serial port
`driver. The ROM BIOS routine, in turn, manages the hardware interrupts from the actual
`
`556
`
`The MS-DOS Encyclopedia
`
`ZTE (USA) 1007, Page 566
`
`
`
`I
`
`r I
`I
`l
`I
`
`.Article 18: Debugging in the MS-DOS Environment
`
`serial device. Thus, Interrupt 14H does not communicate directly with the hardware. All
`the programs in this article deal with software interrupts to the ROM BIOS and MS-DOS.
`
`A program to trace the serial data flow must have access to the serial data, so such a pro(cid:173)
`gram must replace the vector for Interrupt l4H with one that points to itself. The routine
`can then record all the serial data and pass it along through the serial port. Because the
`goal is to minimize the effect of this monitoring on the timing of the data, the method used
`for recording the data should be fast. This requirement rules out writing to a disk file,
`because unexpected delays can be introduced (and because doing disk I/0 from an inter(cid:173)
`rupt service routine under MS-DOS is difficult, if not impossible). Printing the data on
`paper is clearly too slow, and data displayed on the screen is too ephemeral. Thus, about
`the only thing that can be done with the data is to write it to RAM. Luckily, memory has
`become cheap and most personal computers have plenty.
`
`Writing a routine that monitors and records serial data is not enough, however. The data
`must still flow through the serial port to and from the external serial device. Thus, the
`monitor program can have only temporary custody of the data and must pass it on to the
`serial interrupt service routine in the ROM BIOS. This is accomplished by using MS-DOS
`function calls to extract the address of the serial interrupt handler before the new vector is
`installed in its place. The process of intercepting interrupts and then passing the data on is
`known as "daisy-chaining" interrupt handlers. So long as such intercepting programs are
`careful to maintain the data and conditions upon entrance for subsequent routines (that is,
`so long as routines are well behaved; see PROGRAMMING IN THE MS-DOS ENVIRON(cid:173)
`MENT: PRoGRAMMING FOR Ms-oos), several interrupt handlers can be daisy-chained
`together with no detriment to processing. (Woe be unto the person who breaks the daisy
`chain- the results are annoying at best and unpredictable at worst.)
`
`The serial monitoring program, as described so far, correctly collects and stores serial data 4
`
`and then passes it on to the serial port. This may be intellectually satisfying, but it is not of
`much use in the real world. Some way must be provided to control the program- to start
`collection, to stop collection, to pause and resume collection. Also, once data is collected,
`a control function must be provided that returns the number of bytes collected and their
`starting location, so that the data can be examined.
`
`From all this, it is clear that a serial communications monitoring instrument must
`
`1. Replace the Interrupt 14H vector with one pointing to itself.
`2. Save the address of the old interrupt handler.
`3. Collect the serial data, tag it as transmitted or received, and store it in RAM.
`4. Pass the data on, in a completely transparent manner, to the old interrupt handler.
`5. Provide some way to control data collection.
`
`A program that meets all these criteria is shown in Figure 18-4. The COMMSCOP program
`has three major parts:
`
`Section /1· Programming in the MS-DOS Environment
`
`557
`
`ZTE (USA) 1007, Page 567
`
`
`
`PartE: Programming Tools
`
`Procedure
`
`Purpose
`
`COMMSCOPE
`CONTROL
`VECTOR_INIT
`
`Monitoring and tagging
`External control
`Interrupt vector initialization
`
`The COMMSCOPE procedure provides the new Interrupt 14H handler that intercepts the
`serial 1/0 interrupts. The CONTROL procequre provides the external control needed to
`make the system work. The VECTOR_INIT procedure gets the old interrupt handler
`address, installs COMMSCOPE as the new interrupt handler, and installs the interrupt
`handler for the control interrupt.
`
`COMMSCOP IS INSTALLED BY ENTERING
`
`COMMSCOP
`
`COMMSCOP -- COMMUNICATIONS TRACE UTILITY
`TITLE
`**********************************************************************
`; *
`*
`; * COMMSCOP --
`*
`*
`; *
`THIS PROGRAM MONITORS THE ACTIVITY ON A SPECIFIED COMM PORT
`; *
`AND PLACES A COPY OF ALL COMM ACTIVITY IN A RAM BUFFER.
`EACH
`*
`; *
`ENTRY IN THE BUFFER IS TAGGED TO INDICATE WHETHER THE BYTE
`*
`; *
`WAS SENT BY OR RECEIVED BY THE SYSTEM.
`*
`; *
`*
`; *
`*
`; *
`*
`; *
`*
`; *
`*
`; *
`THIS WILL INSTALL COMMSCOP AND SET UP A 64K BUFFER TO BE USED
`*
`; *
`*
`FOR DATA LOGGING. REMEM