home *** CD-ROM | disk | FTP | other *** search
/ The Unsorted BBS Collection / thegreatunsorted.tar / thegreatunsorted / programming / asm_programming / DEBUGTUT.TXT < prev    next >
Text File  |  1986-02-20  |  40KB  |  1,251 lines

  1.  
  2.  
  3.         
  4.                                   Preface
  5.  
  6. This  unsigned  text-file  was downloaded from a BBS in  Houston  Texas  on 
  7. November 3,  1984.  I have added the Title Page, Table of Contents, reorga-
  8. nized  the headings,  added sections which appeared to have been missed  by 
  9. the uploader but probably written by the originator, and made some slight 
  10. grammatical corrections to the more obvious errors I found.
  11.  
  12. The program is formatted for Wordstar printing with the Epson MX100 printer 
  13. set to compressed (17 CPI) mode.  The resulting printout fits on a 5 1/2 by 
  14. 8  1/2  page with about a 3/4 inch margin which leaves room  for  looseleaf 
  15. binder holes.   To print this file with Wordstar, simply load as a Document 
  16. file  set  right  margin to 75 and change use your equivalent  command  for 
  17. compressed  printing (must put at start and end of header and footer  too), 
  18. reformat if necessary, and save, and print.  
  19.  
  20. Note that I set the page offset to 32.   This sets the image on the center 
  21. of the paper and allows a 1-sided to 2-sided copy to overlay nicely with my 
  22. Xerox machine.
  23.  
  24. Robert J. Schniebolk    
  25. Gaithersburg, MD
  26. November 4, 1984
  27.  
  28.  
  29.  
  30.  
  31.  
  32.  
  33.  
  34.  
  35.  
  36.  
  37.  
  38.  
  39.  
  40.  
  41.  
  42.  
  43.  
  44.  
  45.  
  46.  
  47.  
  48.  
  49.  
  50.  
  51.  
  52.  
  53.  
  54.  
  55.  
  56.  
  57.  
  58.  
  59.  
  60.  
  61.  
  62.  
  63.  
  64.  
  65.                               DEBUG Tutorial
  66.  
  67.  
  68.  
  69.  
  70.  
  71.  
  72.  
  73. 
  74.  
  75.  
  76.                            In the Public Domain
  77.  
  78.  
  79.  
  80.  
  81.  
  82.  
  83.  
  84.  
  85.  
  86.  
  87.  
  88.  
  89.  
  90.  
  91.  
  92.  
  93.  
  94.  
  95.  
  96.  
  97.  
  98.  
  99.  
  100.  
  101.                                DEBUG Tutorial                        Page 2
  102.  
  103.                              TABLE OF CONTENTS   
  104.  
  105. 1.  INTRODUCTION........................................................ 3
  106.  
  107. 2.  STARTING DEBUG...................................................... 4
  108.  
  109. 3.  DISPLAY COMMANDS.................................................... 5
  110.     3.1  Register command............................................... 5
  111.     3.2  Dump command................................................... 6
  112.     3.3  Search command................................................. 8   
  113.     3.4  Compare........................................................10 
  114.     3.5  Unassemble command.............................................11
  115.  
  116. 4.  DATA ENTRY..........................................................13
  117.     4.1  Enter..........................................................13
  118.     4.2  Fill...........................................................14
  119.     4.3  Move...........................................................15
  120.     4.4  Assemble.......................................................16
  121.  
  122. 5.  I/O COMMANDS........................................................18
  123.     5.1  Name...........................................................18
  124.     5.2  Load...........................................................18
  125.     5.3  Write..........................................................19
  126.     5.4  Input..........................................................20
  127.     5.5  Output.........................................................20
  128.     5.6  Quit...........................................................20
  129.  
  130. 6.  EXECUTION COMMANDS..................................................21
  131.     6.1  Go.............................................................21
  132.     6.2  Trace..........................................................22
  133.  
  134. 7.  ARITHMETIC..........................................................23
  135.  
  136. 8.  WRAPUP..............................................................24
  137.  
  138.  
  139.  
  140.  
  141.  
  142.  
  143.  
  144.  
  145.  
  146.  
  147.  
  148.  
  149.  
  150.  
  151.                                DEBUG Tutorial                        Page 3
  152.  
  153.                              1.  INTRODUCTION
  154.  
  155. This  tutorial is made to present an overview of the DEBUG.COM program  for 
  156. the IBM PC.  This utility can be extremely useful, when used correctly.  It 
  157. is  almost a must for Assembler Language programmers,  and can also provide 
  158. an  insight  into the operation of the machine at the bit  level.   It  has 
  159. several nice features,  including the ability to display and change any  of 
  160. the  registers in the IBMPC,  start and stop program execution at any time, 
  161. change the program,  and look at diskettes,  sector by sector.  DEBUG works 
  162. at the machine code level, but it does also have the ability to disassemble 
  163. machine code, and (at dos 2.0), assemble instructions directly into machine 
  164. code.
  165.  
  166. The  procedure  for starting DEBUG and command syntax will not  be  covered 
  167. here,  as they are well documented in the DOS manual.   What we will do  is 
  168. show  some  examples of the various commands and the response which is  ex-
  169. pected.   Note that the segment registers will probably not be exactly what 
  170. is shown.  This is normal, and should be expected.
  171.  
  172. For  the examples,  I will be using the demo program CLOCK.COM in  the  XA4 
  173. database.   For those of you with the IBM assembler (MASM),  the source can 
  174. be down loaded.   If you do not have the assembler,  or have another assem-
  175. bler,  the file CLOCK.HEX has been up loaded.  It can be converted to a COM 
  176. file using any of the existing HEX conversion programs on the SIG.  See the 
  177. file CLOCK.DOC for more information.
  178.  
  179.  
  180.  
  181.  
  182.  
  183.  
  184.  
  185.  
  186.  
  187.  
  188.  
  189.  
  190.  
  191.  
  192.  
  193.  
  194.  
  195.  
  196.  
  197.  
  198.  
  199.  
  200.  
  201.                                DEBUG Tutorial                        Page 4
  202.  
  203.                             2.  STARTING DEBUG
  204.  
  205. There are two ways to start DEBUG with a file.   Both ways produce the same 
  206. results, and either can be used.
  207.      
  208.      In the Command Line:  A>DEBUG CLOCK.COM <ENTER>
  209.  
  210.      Separate from the command line:  A>DEBUG <ENTER>
  211.                                       -N CLOCK.COM
  212.                                       -L
  213.  
  214. With either method,  you will get the DEBUG prompt of a hyphen (-).   DEBUG 
  215. has  loaded  your  program and is ready to run.   The description  of  each 
  216. instruction will assume this as a starting point, unless otherwise mention-
  217. ed.   If at any time you get different results,  check your procedure care-
  218. fully.  If it is correct, please leave me a message.  I have tried to check 
  219. everything, but I have been known to make a mistake or two (anyway).
  220.  
  221. If  you do have problems,  you can enter the command Q (Quit) any time  you 
  222. have the DEBUG prompt (-).  This should return you to the DOS prompt.
  223.  
  224.  
  225.  
  226.  
  227.  
  228.  
  229.  
  230.  
  231.  
  232.  
  233.  
  234.  
  235.  
  236.  
  237.  
  238.  
  239.  
  240.  
  241.  
  242.  
  243.  
  244.  
  245.  
  246.  
  247.  
  248.  
  249.  
  250.  
  251.                                DEBUG Tutorial                        Page 5
  252.  
  253.                            3.  DISPLAY COMMANDS
  254.  
  255. 3.1  Register command
  256.  
  257. The first thing we should look at are the registers,  using the R  command.  
  258. If  you type in an R with no parameters,  the registers should be displayed 
  259. as so:
  260.  
  261. AX=0000  BX=0000  CX=0446  DX=0000  SP=FFFE  BP=0000  SI=0000  DI=0000
  262. DS=6897  ES=6897  SS=6897  CS=6897  IP=0100   NV UP DI PL NZ NA PE NC
  263. 6897:0100 E96B01        JMP     026E
  264.  
  265. CX  contains  the length of the file (0446h or 1094d).   If the  file  were 
  266. larger than 64K, BX would contain the high order of the size.  This is very 
  267. important to remember when using the Write command,  as this is the size of 
  268. the file to be written.  Remember, once the file is in memory, DEBUG has no 
  269. idea how large the file is,  or if you may have added to it.  The amount of 
  270. data to be written will be taken from the BX and CX registers.
  271.  
  272. If  we  want to change one of the registers,  we enter R and  the  register 
  273. name.  Let's place 1234 (hexadecimal) in the AX register:
  274.  
  275. -R AX          R and AX register
  276. AX 0000        Debug responds with register and contents
  277. : 1234         : is the prompt for entering new contents.  We respond 1234
  278. -              Debug is waiting for the next command.
  279.  
  280. Now if we display the registers, we see the following:
  281.  
  282. AX=1234  BX=0000  CX=0446  DX=0000  SP=FFFE  BP=0000  SI=0000  DI=0000
  283. DS=6897  ES=6897  SS=6897  CS=6897  IP=0100   NV UP DI PL NZ NA PE NC
  284. 6897:0100 E96B01        JMP     026E
  285.  
  286. Note that nothing has changed,  with the exception of the AX register.  The 
  287. new value has been placed in it,  as we requested.  One note.  The Register 
  288. command can only be used for 16 bit registers (AX,  BX,  etc.).   It cannot 
  289. change the 8 bit registers (AH,  AL,  BH,  etc.).   To change just AH,  for 
  290. instance,  you must enter the the data in the AX register, with your new AH 
  291. and the old AL values.
  292.  
  293.  
  294.  
  295.  
  296.  
  297.  
  298.  
  299.  
  300.  
  301.                                DEBUG Tutorial                        Page 6
  302.  
  303. 3.2  Dump command
  304.  
  305. One of the other main features of DEBUG is the ability to display areas  of 
  306. storage.   Unless  you are real good at reading 8088 machine language,  the 
  307. Dump command is mostly used to display data (text,  flags,  etc.).  To dis-
  308. play code,  the Unassemble command below is a better choice.    If we enter 
  309. the  Dump  command at this time,  DEBUG will default to the  start  of  the 
  310. program.  It uses the DS register as it's default, and, since this is a COM 
  311. file,  begins  at DS:0100.   It will by default display 80h (128d) bytes of 
  312. data,  or the length you specify.   The next execution of the Dump  command 
  313. will display the following 80h bytes,  and so on.    For example, the first 
  314. execution of D will display DS:0100 for 80h bytes, the next one DS:0180 for 
  315. 80h bytes, etc.  Of course, absolute segment and segment register overrides 
  316. can  be  used,  but only hex numbers can be used for the offset,  e D  will 
  317. display DS:0100 for 80h bytes, the next one DS:0180 for 80h bytes, etc.  Of 
  318. course,  absolute segment and segment register overrides can be  used,  but 
  319. only hex numbers can be used for the offset.  That is, D DS:BX is invalid.
  320.  
  321. With our program loaded, if we enter the Dump command, we will see this:
  322.  
  323. 6897:0100 E9 6B 01 43 4C 4F 43 4B-2E 41 53 4D 43 6F 70 79  ik.CLOCK.ASMCopy
  324. 6897:0110 72 69 67 68 74 20 28 43-29 20 31 39 38 33 4A 65  right (C) 1983Je
  325. 6897:0120 72 72 79 20 44 2E 20 53-74 75 63 6B 6C 65 50 75  rry D. StucklePu
  326. 6897:0130 62 6C 69 63 20 64 6F 6D-61 69 6E 20 73 6F 66 74  blic domain soft
  327. 6897:0140 77 61 72 65 00 00 00 00-00 00 00 00 00 00 00 00  ware............
  328. 6897:0150 00 00 00 00 00 00 00 00-00 24 00 00 00 00 00 00  .........$......
  329. 6897:0160 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
  330. 6897:0170 00 00 00 00 00 00 00 00-00 00 00 00 44 4F 53 20  ............DOS
  331.  
  332. Notice  that the output from the Dump command is divided into three  parts.  
  333. On the left, we have the address of the first byte on the line.  This is in 
  334. the format Segment:Offset.
  335.  
  336. Next  comes  the hex data at that location.   Debug will always  start  the 
  337. second line at a 16 byte boundary; that is, if you entered D 109, you would 
  338. get 7 bytes of information on the first line (109-10F), and the second line 
  339. would start at 110.  The last line of data would have the remaining 9 bytes 
  340. of data, so 80h bytes are still displayed.
  341.  
  342.  
  343.  
  344.  
  345.  
  346.  
  347.  
  348.  
  349.  
  350.  
  351.                                DEBUG Tutorial                        Page 7
  352.  
  353. The third area is the ASCII representation of the data.   Only the standard 
  354. ASCII character set is displayed.  Special characters for the IBMPC are not 
  355. displayed; rather periods (.) are shown in their place.  This makes search-
  356. ing for plain text much easier to do.
  357.  
  358. Dump can be used to display up to 64K bytes of data,  with one restriction:  
  359. It  cannot  cross  a segment boundary.   That is,  D 0100 l f000  is  valid 
  360. (display  DS:0100  to DS:F0FF),  but D 9000 l 8000 is not (8000h  +9000h  = 
  361. 11000h and crosses a segment boundary).
  362.  
  363. Since 64K is 10000h and cannot fit into four hex characters, Dump uses 0000 
  364. to indicate 64K.   To display a complete segment, enter D 0 l 0.  This will 
  365. display the total 64K segment.
  366.  
  367. If,  at any time you want to suspend the display of data,  Cntl-NumLock  as 
  368. usual.    If you want to terminate the display,  Cntl-Break will stop itand 
  369. return you to the DEBUG prompt.
  370.  
  371.  
  372.  
  373.  
  374.  
  375.  
  376.  
  377.  
  378.  
  379.  
  380.  
  381.  
  382.  
  383.  
  384.  
  385.  
  386.  
  387.  
  388.  
  389.  
  390.  
  391.  
  392.  
  393.  
  394.  
  395.  
  396.  
  397.  
  398.  
  399.  
  400.  
  401.                                DEBUG Tutorial                        Page 8
  402.  
  403. 3.3  Search command
  404.  
  405. Search is used to find the occurrence of a specific byte or series of bytes 
  406. within  a  segment.  The  address parameters are the same as for  the  Dump 
  407. command,  so we will not duplicate them here.   However,  we also need  the 
  408. data to be searched for.  This data can be entered as either hexadecimal or 
  409. character data.   Hexadecimal data is entered as bytes,   with a space or a 
  410. comma  as  the separator.   Character data is enclosed by single or  double 
  411. quotes.  Hex and character data can be mixed in the same request, i.e. S 01 
  412. 100  12  34 'abc' 56 is valid,  and requests a search from DS:0000  through 
  413. DS:00FF for the sequence of 12h 34h a b c 56h,   in that order.  Upper case 
  414. characters  are different than lower  case  characters,   and a match  will 
  415. not be found if the  case  does  not match.   For  instance,  'ABC'  is not 
  416. the  same  as 'abc' or 'Abc' or any  other combination of upper  and  lower 
  417. case characters.   However,  'ABC' is identical to "ABC",  since the single 
  418. and double quotes are separators only.
  419.  
  420. For example when looking for the string 'Sat', the following would occur:
  421.  
  422.      -S 0 l 0 'Sat'
  423.      6897:0235
  424.      -
  425. The actual segment would be different in your system, but the offset should 
  426. be  the  same.   If we then displayed the data,  we would find  the  string 
  427. 'Saturday' at this location.  We could also search on 'turda', or any other 
  428. combination of characters in the string.   If we wanted to find every place 
  429. we did an Int 21h (machine code for Int is CD), we would do the following:
  430.  
  431.      -S 0 l 0 cd 21
  432.      6897:0050
  433.      6897:0274
  434.      6897:027F
  435.      6897:028B
  436.      6897:02AD
  437.      6897:02B4
  438.      6897:0332
  439.      6897:0345
  440.      6897:034C
  441.      6897:043A
  442.      6897:0467
  443.      6897:047A
  444.      6897:0513
  445.      6897:0526
  446.      6897:0537
  447.      6897:0544
  448.  
  449.  
  450.  
  451.                                DEBUG Tutorial                        Page 9
  452.  
  453. DEBUG found the hex data CD 21 at the above locations.   This does not mean 
  454. that all these addresses are INT 21's,  only that that data was there.   It 
  455. could (and most likely is) an instruction, but it could also be an address, 
  456. the last part of a JMP instruction, etc.  You will have to manually inspect 
  457. the code at that area to make sure it is an INT 21.   (You don't expect the 
  458. machine to do everything, do you?).
  459.  
  460.  
  461.  
  462.  
  463.  
  464.  
  465.  
  466.  
  467.  
  468.  
  469.  
  470.  
  471.  
  472.  
  473.  
  474.  
  475.  
  476.  
  477.  
  478.  
  479.  
  480.  
  481.  
  482.  
  483.  
  484.  
  485.  
  486.  
  487.  
  488.  
  489.  
  490.  
  491.  
  492.  
  493.  
  494.  
  495.  
  496.  
  497.  
  498.  
  499.  
  500.  
  501.                                DEBUG Tutorial                        Page 10
  502.  
  503. 3.4  Compare command
  504.  
  505. Along  the  same lines of Dump and Search commands,  we  have  the  Compare 
  506. command.  Compare will take two blocks of memory and compare them, byte for 
  507. byte.   If  the  two addresses do not contain the  same  information,  both 
  508. addresses are displayed,  with their respective data bytes.  As an example, 
  509. we will compare DS:0100 with DS:0200 for a length of 8.
  510.  
  511.      -d 0100 l 8 0200
  512.      6897:0100  E9  65  6897:0200
  513.      6897:0101  6B  70  6897:0201
  514.      6897:0102  01  74  6897:0202
  515.      6897:0103  43  65  6897:0203
  516.      6897:0104  4C  6D  6897:0204
  517.      6897:0105  4F  62  6897:0205
  518.      6897:0106  43  65  6897:0206
  519.      6897:0107  4B  72  6897:0207
  520.  
  521. None  of the eight bytes compared,  so we got output for each byte.   If we 
  522. had gotten a match on any of the bytes, DEBUG would have skipped that byte.  
  523. If all of the locations requested matched, DEBUG would have simply respond-
  524. ed with another prompt.  No other message is displayed.  This is useful for 
  525. comparing two blocks of data from a file,  or a program with the BIOS  ROM.  
  526. Otherwise, I have not found a great amount of use for it.
  527.  
  528.  
  529.  
  530.  
  531.  
  532.  
  533.  
  534.  
  535.  
  536.  
  537.  
  538.  
  539.  
  540.  
  541.  
  542.  
  543.  
  544.  
  545.  
  546.  
  547.  
  548.  
  549.  
  550.  
  551.                                DEBUG Tutorial                        Page 11
  552.  
  553. 3.5  Unassemble command
  554.  
  555. For  debugging,  one  of the main commands you will use is  the  Unassemble 
  556. command.   This  command will take machine code and convert it to  instruc-
  557. tions.  Addressing is the same as for previous commands with one exception:  
  558. Since  we  are now working with code (the previous commands are mainly  for 
  559. data),  the default register is the CS register.   In a .COM program,  this 
  560. makes  very little difference,  unless you reset the DS register  yourself.  
  561. However,  in a .EXE file, it can make a lot of difference, as the CS and DS 
  562. registers are set to different values.
  563.  
  564. Unassemble data can lead to some interesting results.  For instance, in our 
  565. example,  CS:IP is set to 6897:0100.   If we look at the program,  we see a 
  566. JMP as the first instruction,  followed by data.   If we just enter  U,  we 
  567. will start at CS:IP (6897:0100) and start unassembling data.   What we will 
  568. get is a good instruction, followed by more or less nonsense. For instance:
  569.  
  570.      -U
  571.      6897:0100 E96B01        JMP     026E
  572.      6897:0103 43            INC     BX
  573.      6897:0104 4C            DEC     SP
  574.      6897:0105 4F            DEC     DI
  575.      6897:0106 43            INC     BX
  576.      6897:0107 4B            DEC     BX
  577.  
  578. And so on through 6897:011D. We know the INC BX, DEC SP, etc. are not valid 
  579. instructions,  but DEBUG doesn't, so we do have to look at the code.  After 
  580. working with DEBUG a little, you will be able to spot code versus data with 
  581. the Unassemble command.  For now, suffice to say that the first instruction 
  582. will take us to CS:026E and we can start from there.
  583.  
  584.  
  585.  
  586.  
  587.  
  588.  
  589.  
  590.  
  591.  
  592.  
  593.  
  594.  
  595.  
  596.  
  597.  
  598.  
  599.  
  600.  
  601.                                DEBUG Tutorial                        Page 12
  602.  
  603. If we Unassemble CS:026E,  we will find something which looks a little more 
  604. like what we expect.  We get:
  605.  
  606.      -U 26E
  607.      6897:026E 8D167802      LEA     DX,[0278]
  608.      6897:0272 B409          MOV     AH,09
  609.      6897:0274 CD21          INT     21
  610.      6897:0276 EB05          JMP     027D
  611.      6897:0278 1B5B32        SBB     BX,[BP+DI+32]
  612.      6897:027B 4A            DEC     DX
  613.      6897:027C 24B4          AND     AL,B4
  614.      6897:027E 30CD          XOR     CH,CL
  615.      6897:0280 213C          AND     [SI],DI
  616.      6897:0282 027D0A        ADD     BH,[DI+0A]
  617.      6897:0285 8D167C01      LEA     DX,[017C]
  618.      6897:0289 B409          MOV     AH,09
  619.      6897:028B CD21          INT     21
  620.      6897:028D CD20          INT     20
  621.  
  622. The first few instructions look fine.  But after the JMP 027D, things start 
  623. to look a little funny.   Also,  note that there is no instruction starting 
  624. at  027D.   We have instructions at 027C and 027E,  but not 027D.   This is 
  625. again  because  DEBUG doesn't know data from  instructions.   At  027C,  we 
  626. should (and do) have the end of our data.   But this also translates into a 
  627. valid AND instruction,  so DEBUG will treat it as such.   If we wanted  the 
  628. actual  instruction  at 027D,  we could enter U 027D and get it,  but  from 
  629. here,  we don't know what it is.   What I'm trying to say is, DEBUG will do 
  630. what ever you tell it.  If you tell it to Unassemble data, it will do so to 
  631. the best of its ability.   So,  you have to make sure you have instructions 
  632. where you think you do.
  633.  
  634.  
  635.  
  636.  
  637.  
  638.  
  639.  
  640.  
  641.  
  642.  
  643.  
  644.  
  645.  
  646.  
  647.  
  648.  
  649.  
  650.  
  651.                                DEBUG Tutorial                        Page 13
  652.  
  653.                               4.  DATA ENTRY
  654.  
  655. 4.1  Enter command
  656.  
  657. The  Enter command is used to place bytes of data in memory.   It  has  two 
  658. modes:  Display/Modify and Replace.  The difference is in where the data is 
  659. specified - in the Enter command itself, or after the prompt.
  660.  
  661. If you enter E address alone,  you are in display/modify mode.   DEBUG will 
  662. prompt  you one byte at a time,  displaying the current byte followed by  a 
  663. period.  At this time, you have the option of entering one or two hexadeci-
  664. mal  characters.   If  you  hit the space bar,  DEBUG will not  modify  the 
  665. current byte,  but go on to the next byte of data.   If you go too far, the 
  666. hyphen (-) will back up one byte each time it is pressed.
  667.  
  668.      E 103
  669.      6897:0103  43.41   4C.42   4F.43   43.     4B.45
  670.      6897:0108  2E.46   41.40   53.-
  671.      6897:0109  40.47   53.
  672.  
  673. In this example,  we entered E 103.   DEBUG responded with the address  and 
  674. the information at that byte (43).   We entered the 41 and DEBUG automatic-
  675. ally showed the next byte of data (4C).   Again,  we entered 42, debug came 
  676. back.  The next byte was 4F, we changed it to 43.  At 106, 43 was fine with 
  677. us,  so we just hit the space bar.  DEBUG did not change the data, and went 
  678. on to the following bytes.   After entering 40 at location 109, we found we 
  679. had entered a bad value.   The hyphen key was pressed,  and DEBUG backed up 
  680. one  byte,  displaying the address and current contents.   Note that it has 
  681. changed  from the original value (41) to the value we typed  in  (40).   We 
  682. then type in the correct value and terminate by pressing the ENTER key.
  683.  
  684. As you can see, this can be very awkward, especially where large amounts of 
  685. data are concerned.  Also, if you need ASCII data, you have to look up each 
  686. character and enter its hex value.  Not easy, to be sure.  That's where the 
  687. Replace mod of operation comes in handy.   Where the Display/Modify mode is 
  688. handy for changing a few bytes at various offsets,  the Replace mode is for 
  689. changing several bytes of information at one time.   Data can be entered in 
  690. hexadecimal  or character format,  and multiple bytes can be entered at one 
  691. time without waiting for the prompt.  If you wanted to store the characters 
  692. 'My name' followed by a hexadecimal 00 starting at location 103, enter:
  693.      E 103 'My name' 0
  694.  
  695. As in the Search command,  data can be entered in character (in quotes)  or 
  696. hexadecimal  forms and can be mixed in the same command.   This is the most 
  697. useful way of entering large amounts of data into memory.
  698.  
  699.  
  700.  
  701.                                DEBUG Tutorial                        Page 14
  702.  
  703. 4.2  Fill
  704.  
  705. The Fill command is useful for storing a lot of data of the same data.   It 
  706. differs from the Enter command in that the list will be repeated until  the 
  707. requested  amount  of  memory is filled.   If the list is longer  than  the 
  708. amount of memory to be filled, the extra items are ignored.  Like the Enter 
  709. command,  it  will take hexadecimal or character data.   Unlike  the  Enter 
  710. command,  though,  large  amounts of data can be stored without  specifying 
  711. every character.  As an example, to clear 32K (8000h) of memory to 00h, you 
  712. only need to enter:
  713.  
  714.      F 0 L 8000 0
  715.  
  716. Which translates into Fill,  starting at DS:0000 for a Length of 32K (8000) 
  717. with 00h.   If the data were entered as '1234',  the memory would be filled 
  718. with the repeating string '123412341234',  etc.   Usually,  it is better to 
  719. enter small amounts of data with the Enter command, because an error in the 
  720. length parameter of the Fill command can destroy a lot of work.   The Enter 
  721. command,  however,  will  only change the number of bytes actually entered, 
  722. minimizing the effects of a parameter error.
  723.  
  724.  
  725.  
  726.  
  727.  
  728.  
  729.  
  730.  
  731.  
  732.  
  733.  
  734.  
  735.  
  736.  
  737.  
  738.  
  739.  
  740.  
  741.  
  742.  
  743.  
  744.  
  745.  
  746.  
  747.  
  748.  
  749.  
  750.  
  751.                                DEBUG Tutorial                        Page 15
  752.  
  753. 4.3  Move
  754.  
  755. The  Move command does just what it says - it moves data around inside  the 
  756. machine.  It takes bytes from with the starting address and moves it to the 
  757. ending address.   If you need to add an instruction into a program,  it can 
  758. be  used to make room for the instruction.   Beware,  though.   Any data or 
  759. labels referenced after the move will not be in the same place.   Move  can 
  760. be  used  to save a part of the program in free memory while you play  with 
  761. the program,  and restore it at any time.   It can also be used to copy ROM 
  762. BIOS into memory,  where it can be written to a file or played with to your 
  763. heart's content.   You can then change things around in BIOS without having 
  764. to worry about programming a ROM.
  765.  
  766.      M 100 L 200 ES:100
  767.  
  768. This will move the data from DS:0100 to DS:02FF (Length 200) to the address 
  769. pointed to by ES:0100.  Later, if we want to restore the data, we can say:
  770.  
  771.      M ES:100 L 200 100
  772.  
  773. which will move the data back to its starting point.   Unless the data  has 
  774. been changed while at the temporary location (ES:0100), we will restore the 
  775. data to its original state.
  776.  
  777.  
  778.  
  779.  
  780.  
  781.  
  782.  
  783.  
  784.  
  785.  
  786.  
  787.  
  788.  
  789.  
  790.  
  791.  
  792.  
  793.  
  794.  
  795.  
  796.  
  797.  
  798.  
  799.  
  800.  
  801.                                DEBUG Tutorial                        Page 16
  802.  
  803. 4.4  Assemble
  804.  
  805. I purposely left the Assemble command to the end, as it is the most complex 
  806. of the data entry commands.  It will take the instructions in the assembler 
  807. language and convert them to machine code directly.   Some of the things it 
  808. can't do,  however,  are:   reference labels,  set equates,  use macros, or 
  809. anything  else which cannot be translated to a value.   Data locations have 
  810. to  be referenced by the physical memory  address,  segment  registers,  if 
  811. different from the defaults,  must be specified,  and RET instructions must 
  812. specify the type (NEAR or FAR) of return to be used.   Also, if an instruc-
  813. tion references data but not registers (i.e.  Mov [278],5), the Byte ptr or 
  814. Word  ptr  overrides must be specified.   One other restriction:   To  tell 
  815. DEBUG the difference between moving 1234h into AX and moving the data  from 
  816. location  1234  into AX,  the latter is coded as Mov AX,[1234],  where  the 
  817. brackets indicate the reference is an addressed location.   The differences 
  818. between MASM and DEBUG are as follows:
  819.  
  820.      MASM                DEBUG                 Comments
  821.  
  822.      Mov  AX,1234        Mov  AX,1234          Place 1234 into AX
  823.      Mov  AX,L1234       Mov  AX,[1234]        Contents of add. 1234 to AX
  824.      Mov  AX,CS:1234     CS:Mov AX,[1234]      Move from offset of CS.
  825.      Movs Byte ptr ...   Movesb                Move byte string
  826.      Movs Word ptr ...   Movsw                 Move word string
  827.      Ret                 Ret                   Near return
  828.      Ret                 Retf                  Far return
  829.  
  830. Also,  Jmp instructions will be assembled automatically to Short,  Near, or 
  831. Far Jmps.   However,  the Near and Far operands can be used to override the 
  832. displacement if you do need them.  Let's try a very simple routine to clear 
  833. the screen.
  834.  
  835.      -A 100
  836.      6897:0100 MOV AX,600
  837.      6897:0103 MOV CX,0
  838.      6897:0106 MOV DX,184f
  839.      6897:0109 MOV BH,07
  840.      6897:010B INT 10
  841.      6897:010D INT 20
  842.      6897:010F
  843.      -
  844.  
  845.  
  846.  
  847.  
  848.  
  849.  
  850.  
  851.                                DEBUG Tutorial                        Page 17
  852.  
  853. We  are using BIOS interrupt 10h,  which is the video interrupt.   (If  you 
  854. would like more information on the interrupt, there is a very good descrip-
  855. tion in the Technical Reference Manual.)  We need to call BIOS with AX=600, 
  856. BH=7, CX=0, and DX=184Fh.  First we had to load the registers, which we did 
  857. at  in  the  first four instructions.   The statement at  offset  6897:010B 
  858. actually called BIOS.   The INT 20 at offset 010D is for safety  only.   We 
  859. really don't need it,  but with it in, the program will stop automatically.  
  860. Without  the INT 20,  and if we did not stop,  DEBUG would try and  execute 
  861. whatever occurs at 010F.  If this happens to be a valid program (unlikely), 
  862. we would just execute the program.   Usually, though, we will find it to be 
  863. invalid,  and will probably hang the system, requiring a Ctrl-Alt-Del (may-
  864. be) or a power-off and on again (usually).  So, be careful and double check 
  865. your work!
  866.  
  867. Now,  we  need to execute the program which will probably hang the  system,  
  868. requiring  a  Ctrl-Alt-Del (maybe) or a power-off and on  again  (usually).  
  869. So,  be careful and double check your work!   To proceed,  enter the G com-
  870. mand,  a  G  followed by the enter key.   If you have entered  the  program 
  871. correctly,  the screen will clear and you will get a message "Program  ter-
  872. minated  normally".  (More on the Go command later).
  873.  
  874. Again,  I cannot stress the importance of checking your work when using the 
  875. Assemble command.   The commands may assemble correctly, but cause a lot of 
  876. problems.   This  is  especially important for the Jmp and  Call  commands; 
  877. since they cause an interruption in the flow of the program, they can cause 
  878. the program to jump into the middle of an instruction,  causing VERY unpre-
  879. dictable results.
  880.  
  881.  
  882.  
  883.  
  884.  
  885.  
  886.  
  887.  
  888.  
  889.  
  890.  
  891.  
  892.  
  893.  
  894.  
  895.  
  896.  
  897.  
  898.  
  899.  
  900.  
  901.                                DEBUG Tutorial                        Page 18
  902.  
  903.                              5.  I/O COMMANDS
  904.  
  905. 5.1  Name
  906.  
  907. The Name command has just one purpose - specifying the name of a file which 
  908. DEBUG  is  going to Load or Write.   It does nothing to  change  memory  or 
  909. execute a program,  but does prepare a file control block for DEBUG to work 
  910. with.   If you are going to load a program,  you can specify any parameters 
  911. on the same line,  just like in DOS.  One difference is, the extension MUST 
  912. be specified.   The default is no extension.   DEBUG will load or write any 
  913. file, but the full file name must be entered.
  914.  
  915.      -N CHKDSK.COM /F
  916.  
  917. This  statement prepares DEBUG for loading the program  CHKDSK.COM  passing 
  918. the /F switch to the program.  When the Load (see below) command is execut-
  919. ed,  DEBUG  will load CHKDSK.COM and set up the parameter list (/F) in  the 
  920. program's input area.
  921.  
  922.  
  923. 5.2  Load
  924.  
  925. The Load command has two formats.   The first one will load a program which 
  926. has been specified by the Name command into storage, set the various regis-
  927. ters,  and prepare for execution.   Any program parameters in the Name com-
  928. mand  will be set into the Program Segment Prefix,  and the program will be 
  929. ready  to run.   If the file is a .HEX file,  it is assumed to  have  valid 
  930. hexadecimal characters representing memory values,  two hexadecimal charac-
  931. ters  per  byte.   Files are loaded starting at CS:0100 or at  the  address 
  932. specified in the  command.  For .COM. .HEX and .EXE files, the program will 
  933. be loaded, the registers set, and CS:IP set to the first instruction in the 
  934. program.   For other files,  the registers are undetermined, but basically, 
  935. the  segment registers are set to the segment of the PSP (100h bytes before 
  936. the  code is actually loaded),  and BX and CX are set to the  file  length.  
  937. Other registers are undetermined
  938.  
  939.      -N CLOCK.COM
  940.      -L
  941.  
  942. This sequence will load CLOCK.COM into memory, set IP to the entry point of 
  943. 0100,  and  CX will contain 0446,  the hexadecimal size of the  file.   The 
  944. program is now ready to run.
  945.  
  946. The  second form of the Load command does not use the Name command.   It is 
  947. used  to  load absolute sectors from the disk (hard or soft)  into  memory.  
  948.  
  949.  
  950.  
  951.                                DEBUG Tutorial                        Page 19
  952.  
  953. The sector count starts with the first sector of track 0 and continuing  to 
  954. the end of the track.   The next sector is track 0,  second side (if double 
  955. sided),  and continues to the end of that sector.   Then, back to the first 
  956. side,  track  1,  and so on,  until the end of the disk.   Up to 80h (128d) 
  957. sectors  can  be loaded at one time.   To use,  you must  specify  starting 
  958. address,  drive (0=A, 1=B, etc.), starting sector, and number of sectors to 
  959. load.
  960.  
  961.      -L 100 0 10 20
  962.  
  963. This instruction tells DEBUG to load,  starting at DS:0100,  from drive  A, 
  964. sector  10h  for  20h sectors.   DEBUG can sometimes be used  this  way  to 
  965. recover part of the information on a damaged sector.   If you get an error, 
  966. check the memory location for that data.  Often times, part of the data has 
  967. been  transferred before the error occurs and the remainder (especially for 
  968. text files) can be manually entered.   Also,  repetitive retrys will  some-
  969. times  get the information into memory.   This can then be rewritten on the 
  970. same diskette (see the Write command below),  or copied to the same  sector 
  971. on another diskette.  In this way, the data on a damaged disk can sometimes 
  972. be recovered.
  973.  
  974.  
  975. 5.3  Write
  976.  
  977. The write command is very similar to the Load command.  Both have two modes 
  978. of operation,  and both will operate on files or absolute sectors.   As you 
  979. have  probably guessed,  the Write command is the opposite of the Load com-
  980. mand.   Since all the parameters are the same, we will not cover the syntax 
  981. in detail.   However, one thing worth mentioning:  When using the file mode 
  982. of the Write command,  the amount of data to be written is specified in  BX 
  983. and CX, with BX containing the high-order file size.  The start address can 
  984. be specified or is defaulted to CS:0100.   Also, files with an extension of 
  985. EXE or HEX cannot be written out,  and error message to that effect will be 
  986. displayed.  If you do need to change a .EXE or .HEX file, simply rename and 
  987. load  it,  make  your  changes,  save it and name it back to  its  original 
  988. filename.
  989.  
  990.  
  991.  
  992.  
  993.  
  994.  
  995.  
  996.  
  997.  
  998.  
  999.  
  1000.  
  1001.                                DEBUG Tutorial                        Page 20
  1002.  
  1003. 5.4  Input
  1004.  
  1005. The  Input  command is used to access data from the machine's input  ports.  
  1006. The Input command must specify the desired port.  Invocation of the command 
  1007. will provide a one byte response from the selected port.  For example:
  1008.  
  1009.      -I 3F8
  1010.       7D
  1011.      -
  1012.  
  1013. This is the Line input port for the first Asynchronous adapter.   Your data 
  1014. may  be  different,  as it depends on the current status of the  port.   It 
  1015. indicates the data in the register at the time it was read was 7Dh.  Depen-
  1016. ding on the port,  this data may change, as the ports are not controlled by 
  1017. the PC.
  1018.  
  1019.  
  1020. 5.5.  Output
  1021.  
  1022. As  you can probably guess,  the Output command is the reverse of the Input 
  1023. command.  You can use the Output command to send a single byte of data to a 
  1024. port.   Note  that certain ports can cause the system to  hang  (especially 
  1025. those dealing with system interrupts and the keyboard),  so be careful with 
  1026. what you send where!
  1027.  
  1028.      -O 3FC 1
  1029.      -
  1030.  
  1031. Port  3FCh  is the modem control register for the first asynchronous  port.  
  1032. Sending  a 01h to this port turns on the DTR (Data Terminal Ready) bit.   A 
  1033. 00h  will turn all the bits off.  If you have a modem which indicates  this 
  1034. bit, you can watch the light flash as you turn the bit on and off.
  1035.  
  1036.  
  1037. 5.6  Quit
  1038. This command needs no explanation,  however, you must remember to write all 
  1039. data to the desired file prior to exercising this command as the result  is 
  1040. an immediate exit from the program.
  1041.  
  1042.       -Q
  1043. A>
  1044.  
  1045. (Although not really an I/O comand for debugging a program,  this command is 
  1046. certainly an out from Debug.)
  1047.  
  1048.  
  1049.  
  1050.  
  1051.                                DEBUG Tutorial                        Page 21
  1052.  
  1053. 6.  EXECUTION COMMANDS
  1054.  
  1055. 6.1  Go
  1056.  
  1057. The Go command is used to start program execution.   A very versatile  com-
  1058. mand,  it  can be used to start the execution at any point in the  program, 
  1059. and optionally stop at any of ten points (breakpoints) in the program.   If 
  1060. no  breakpoints  are  set (or the breakpoints are  not  executed),  program 
  1061. execution continues until termination,  in which case the message  "Program 
  1062. terminated normally" is sent.   If a breakpoint is executed, program execu-
  1063. tion  stops,  the current registers are displayed,  and the DEBUG prompt is 
  1064. displayed.   Any  of the DEBUG commands can be executed,  including the  Go 
  1065. command to continue execution.   Note that the Go command CANNOT be termin-
  1066. ated  by  Ctrl-break.   This  is one of the few commands  which  cannot  be 
  1067. interrupted while executing.
  1068.  
  1069.      -G = 100
  1070.  
  1071. The Go command without breakpoints starts program execution at the  address 
  1072. (in  this case CS:0100) in the command.   The equal sign before the address 
  1073. is  required.   (Without the equal sign,  the address is taken as a  break-
  1074. point.)  If no starting address is specified,  program execution starts  at 
  1075. CS:IP.   In this case,  since no breakpoints are specified,  CLOCK.COM will 
  1076. continue  execution  until  the cntl-break key is pressed and  the  program 
  1077. terminates.   At  this time,  you will get the message "Program  terminated 
  1078. normally".  Note that, after the termination message, the program should be 
  1079. reloaded  before being executed.   Also,  any memory  alterations  (storing 
  1080. data, etc.) will not be restored unless the program is reloaded.
  1081.  
  1082.      -G 276 47C 528 347
  1083.  
  1084. This  version of the control command will start the program and set  break-
  1085. points at CS:276, CS:47C, CS:528 and CS:347.  These correspond to locations 
  1086. in CLOCK.COM  after the screen is cleared,  and the day,  date and time are 
  1087. displayed,  respectively.  The program will stop at whichever breakpoint it 
  1088. hits first.   Note that the second and third breakpoints will only be  dis-
  1089. played at two times - when the program is started and at midnight.   If you 
  1090. care  to  stay  up (or just change the time in the  computer),  and  set  a 
  1091. breakpoint at 47C, this will stop when the program is started, and again at 
  1092. midnight.
  1093.  
  1094. Some notes about breakpoints.  The execution stops just before the instruc-
  1095. tion is executed.   Setting a breakpoint at the current instruction address 
  1096. will  not execute any instructions.   DEBUG will set the breakpoint  first, 
  1097. then try to execute the instruction, causing another breakpoint.  Also, the 
  1098.  
  1099.  
  1100.  
  1101.                                DEBUG Tutorial                        Page 22
  1102.  
  1103. breakpoints use Interrupt 3 to stop execution.   DEBUG intercepts interrupt 
  1104. 3 to stop the program execution and display the registers.  Finally, break-
  1105. points are not saved between Go commands.  Any breakpoints you want will be 
  1106. have to be set with each Go command.
  1107.  
  1108.  
  1109. 6.2  Trace
  1110.  
  1111. Along  the same lines as Go is the Trace command.   The difference is that, 
  1112. while  Go  executes a whole block of code at one time,  the  Trace  command 
  1113. executes  instructions one at a time,  displaying the registers after  each 
  1114. instruction.   Like  the Go instruction,  execution can be started  at  any 
  1115. address.   The  start  address  again must be preceeded by an  equal  sign.  
  1116. However,  the  Trace command also has a parameter to indicate how many  in-
  1117. structions are to be executed.
  1118.  
  1119.      -T =100 5
  1120.  
  1121. This  Trace  command will start at CS:100 and  execute  five  instructions.  
  1122. Without  the address,  execution will start at the current CS:IP value  and 
  1123. continue for five instructions.  T alone will execute one instruction.
  1124.  
  1125. When using Trace to follow a program,  it is best to go around calls to DOS 
  1126. and interrupts, as some of the routines involved can be lengthy.  Also, DOS 
  1127. cannot be Traced,  and doing so has a tendency to hang the system.   There-
  1128. fore,  Trace  to the call or interrupt and Go to the next address after the 
  1129. call or interrupt.
  1130.  
  1131.  
  1132.  
  1133.  
  1134.  
  1135.  
  1136.  
  1137.  
  1138.  
  1139.  
  1140.  
  1141.  
  1142.  
  1143.  
  1144.  
  1145.  
  1146.  
  1147.  
  1148.  
  1149.  
  1150.  
  1151.                                DEBUG Tutorial                        Page 23
  1152.  
  1153.                           7.  ARITHMETIC COMMANDS
  1154.  
  1155. 7.1  Hexarithmetic
  1156.  
  1157. The  Hexarithmetic command is handy for adding and subtracting  hexadecimal 
  1158. numbers.   It  has  just two parameters - the two numbers to be  added  and 
  1159. subtracted.   DEBUG's  response  is the sum and difference of the  numbers.  
  1160. The numbers can be one to four hexadecimal digits long.   The addition  and 
  1161. subtraction are unsigned, and no carry or borrow is shown beyond the fourth 
  1162. (high order) digit.
  1163.  
  1164.      -H 5 6
  1165.      000B FFFF
  1166.      -H 5678 1234
  1167.      68AC 4444
  1168.      -
  1169.  
  1170. In the first example,  we are adding 0005 and 0006.   The sum is 000B,  the 
  1171. difference is -1.   However,  since there is no carry, we get FFFF.  In the 
  1172. second  example,  the sum of 5678 and 1234 is 68AC,  and the difference  is 
  1173. 4444.
  1174.  
  1175.  
  1176.  
  1177.  
  1178.  
  1179.  
  1180.  
  1181.  
  1182.  
  1183.  
  1184.  
  1185.  
  1186.  
  1187.  
  1188.  
  1189.  
  1190.  
  1191.  
  1192.  
  1193.  
  1194.  
  1195.  
  1196.  
  1197.  
  1198.  
  1199.  
  1200.  
  1201.                                DEBUG Tutorial                        Page 24
  1202.  
  1203.                                 8.  WRAPUP
  1204.  
  1205. If you give it a chance, DEBUG can be a very useful tool for the IBMPC.  It 
  1206. is  almost a requirement for debugging assembler language programs,  as  no 
  1207. nice error messages are produced at run time.   DEBUG does work at the base 
  1208. machine level,  so you need some experience to use it effectively, but with 
  1209. practice, it will be your most useful assembler language debugging tool.
  1210.  
  1211.  
  1212.  
  1213.  
  1214.  
  1215.  
  1216.  
  1217.  
  1218.  
  1219.  
  1220.  
  1221.  
  1222.  
  1223.  
  1224.  
  1225.  
  1226.  
  1227.  
  1228.  
  1229.  
  1230.  
  1231.  
  1232.  
  1233.  
  1234.  
  1235.  
  1236.  
  1237.  
  1238.  
  1239.  
  1240.  
  1241.  
  1242.  
  1243.  
  1244.  
  1245.  
  1246.  
  1247.  
  1248.  
  1249.  
  1250.  
  1251.