....|....|....|....|....|....|...|....|....|....|....|....|....|..... Alphanso's Assembler Assylum Assembly Language Programming for the Beginner by Dave Heyliger - AMUS Debugging Your Programs with FIX This month's session will take a quickie look at a super tool for assembly language programmers called FIX. FIX.LIT comes with you Alpha Micro and resides in the SYS: account, and boy is it slick! FIX allows you to "walk through" your .LIT programs step-by-step (or leap-by-leap), watch how the 16 registers in the Motorola chip change as your program runs, AND watch how your user memory changes as the program runs. In order to demonstrate some of the commands that FIX allows, everyone out in AMUS-land should be "FIXing" the same program. Therefore, I will demonstrate FIX using a previous file discussed via the Assylum called ECHOLN. ECHOLN was presented in the February .LOG and is available off the Network if you don't already have this file. Be sure to assemble (M68 ECHOLN) the file ECHOLN.M68 before you continue with this article. Also, type SET OCTAL so numbers will be consistent. Last but not least, print out the file ECHOLN.M68 so you can refer to this listing while playing around with FIX. Firing Up FIX FIX operates on binary file types only, so simply type FIX ECHOLN [cr] - the default is ECHOLN.LIT. If you assembled ECHOLN with no symbolic listing file (which is the case for most), FIX will report to you that the symbolic file was not found. Egnor this message. After this (quick) message display, you will then be inside the program FIX and at command mode (it looks just like the VUE command mode for the most part). From now on, imagine ECHOLN "running" but running only when you allow it to run - usually line-by-line. ECHOLN at this particular time is at a stand-still; you have not allowed it to run... at least not yet. AlphaFIX/L 1.2(137) Status: Disassembly (PRG)=05173116=octal Debugging ECHOLN.LIT >cursor is here Registers: D0: 0 D1: 0 D2: 0 D3: 0 D4: 0 D5: 0 D6: 0 D7: 0 A0: 0 A1: 0 A2: 216211 A3: 0 A4: 0 A5: 0 A6: 0 SP: 143120 PC Cursor Status: X N Z V C Trace Spvsr Int Mask 00000012(PRG) 00000012(PRG) 0 0 0 0 0 0 0 0 Notice that all 16 registers are listed below the command prompt (the ">"). Notice further that register A2 has a non-zero value as does register A7 (the SP). If you have been following the series, you should remember that A2 "points" to the first non-blank character after the name of the .LIT file entered during runtime (in this case, a [cr]). The address value for A2 is actually a value inside system memory that was defined via the TRMDEF statement for your particular terminal (your input/output buffer definitions). You should have also remembered that register A7 is YOUR unique stack pointer, and that the SP is pointing to the "bottom" of your stack (see the March .LOG submission for details). Notice also the Status Register Flags denoted by Status: X N Z V C. FYI: X = Parity, N = Negitive, Z = Zero, V = Overflow, and C = Carry. A "1" under one of these letters indicates "true" to the flag, i.e., a "1" under the N flag means that the last operation or instruction in the program caused a negitive result. Disregard for the moment the remaining information supplied by FIX and hit an ESCape at this time. You should see the following: 00000012(PRG) PUSH #120 00000020(PRG) PUSH 00000022(PRG) LEA A6,@SP 00000024(PRG) GETMEM 00000026(PRG) BEQ 32 00000030(PRG) EXIT 00000032(PRG) POP A5 00000034(PRG) POP 00000036(PRG) LEA A3,@A5 00000040(PRG) LIN 00000042(PRG) BNE 106 00000044(PRG) TYPE Usage: Echoln {line input} 00000102(PRG) JMP 130 00000106(PRG) MOVB (A2)+,(A3)+ 00000110(PRG) LIN 00000112(PRG) BEQ 120 00000114(PRG) JMP 106 00000120(PRG) CLRB @A3 00000122(PRG) LEA A3,@A5 00000124(PRG) LEA A6,@A3 00000126(PRG) TTYL 00000130(PRG) CRLF 00000132(PRG) EXIT 05173252(ABS) ORB #0,D0 ECHOLN is a good program example in that the entire program "fits" on one screen. Notice the EXIT code at the bottom of you screen. This is the last line of ECHOLN before the END marker. Any "instruction" following EXIT from within FIX is really NOT an instruction but some "binary junk" inside your user memory. FIX is trying to decipher this "junk" into instructions. Remember, instructions - or binary code - is just a series of numbers. When you type in a program name, this program (actually a series of numbers) is loaded into you user memory partition (note the (PRG)). Anything after the (PRG) is still disassembled via FIX but is never used or executed. Again hit an ESCape to get back to the command mode. Now type in a Q for "quit". You should be back at the dot. FIXing ECHOLN with some Line Input Since ECHOLN expects some line input, enter in FIX ECHOLN WOW!. The WOW! will now be our line input when we "walk-through" ECHOLN step-by-step. In other words, register A2 will be pointing to the first W of WOW. Let's actually see if this is true. From command mode (the >) type VIEW @A2. Think of this command as "view memory starting at ("@") A2". You should see the following display (partial listing given - yours may differ slightly. See "Column Breakdown" below for further details). Memory Display from @A2 (Effective address 216210) 00216210 040 127 053440 12710053517 W [M7X] 4.4074212215E13 00216212 117 127 053517 12723606441 OW [M81] 5.6913823794E13 00216214 041 015 006441 01510200012 !. [BDA] 1.2403000998E-31 00216216 012 000 000012 00002453524 .. [ J] 0 00216220 124 127 053524 12725052050 TW [M86] 5.8364478522E13 00216222 050 124 052050 12412005015 (T [MRX] 7.2172314982E11 00216224 015 012 005015 01203247000 .. [AXM] 1.7008933555E-33 (1) (2) (3) (4) (5) (6) (7) (8) Column Breakdown: (1) : Effective address value (byte number) (2) & (3) : ASCII (4) : word (5) : longword (6) : byte (7) : RAD50 (8) : floating point Notice that WOW! shows up and that A2 knows where WOW! resides. Hitting an ESCape will place us back into ECHOLN. The cursor should be resting by the instruction line PUSH #120. With your ECHOLN.M68 listing beside you, see if you can "see" the listing match-up from within FIX. Some lines are word-for-word, while other lines don't match up at all! Why is that? Remember, many monitor calls we continue to employ are actually small macros (think mini-command files). Each monitor call actually exists of a series of assembly codes (as a command file contains a series of dot commands). FIX sometimes will not list the monitor calls but instead list each instruction contained within the monitor call. This explains the slight difference in "source" listings (some monitor calls ARE listed). Now let's "walk" ECHOLN a bit. Your cursor should still be resting by the PUSH #120. Hit returns until you PASS the line LEA A3,@A5 (from the .M68 file, this is line LEA A3,LINE(A5)). Your cursor should be resting by the line LIN. When the returns were hit, ECHOLN was actually "running" each line the cursor passed. Therefore, at this particular time, A3 should be pointing to YOUR memory partition where the variable LINE lives. Hit an ESCape now to return to command mode and check out your user partition by typing VIEW @A3. You should see at this time a series of zeros (no data has yet been moved into the variable LINE). Again hit an escape, and notice that AMOS has placed you inside of ECHOLN right where you left off. The next four lines of ECHOLN were the "error lines". If no input was typed in after ECHOLN, then the Usage message would appear. Since we have placed some data after ECHOLN, notice that when you hit returns (slowly) how the cursor will branch to MOVB (A2)+,(A3)+ (label LINEIN: from the source code printout) right after the LIN instruction. One more item to notice: the BNE 106 will branch the cursor to program instruction 106. The 106 was calculated by AMOS during assembly and is equivalent to the label LINEIN. Your cursor is now resting beside MOVB (A2)+,(A3)+. Remember, A2 points to the line input WOW! and A3 points to your user memory partition where the variable LINE lives. ECHOLN is now ready to move byte-by-byte the word WOW! into LINE. Before you hit any more returns, hit an ESCape and make a note of the values for registers A2 and A3. Again hit an ESCape; you have returned to MOVB (A2)+,(A3)+. Hit four returns at this time. This will simulate ECHOLN for "one pass" of the transfer of bytes. Notice that the cursor has jumped back to the line MOVB (A2)+,(A3)+. Hit an ESCape to transfer FIX to command mode. Notice that both register A2 and register A3 have been incremented by one via the ()+ notation in the source code. A2 is now pointing at "O" and A3 is now pointing to the next "free" byte in the variable LINE. Transfer FIX back into "run" mode with an ESCape, and continue hitting returns until the cursor branches to CLRB @A3. Hit one more return now. This has the effect of placing a 0 into the byte pointed to by A3. Now hit two more returns until you are at the TTYL command. A3 is pointing to the variable LINE at this time. Lets inspect the user memory partition. Hit an ESCape to enter command mode and type VIEW @A3. How about that! WOW! is in your user memory partition. Notice that the byte after the "!" is a zero (null) and not an ascii zero (48). Remember, TTYL will type out a line of ascii data, the line terminated with a null. Hit an ESCape to return to the source of ECHOLN. Your cursor should be resting beside the TTYL command. Hitting a return now will actually execute the TTYL command. You should see WOW! printed to your screen. Two more returns and you are at the end of ECHOLN. An ESCape and a Q will return you to the dot. Speed Reading with FIX Now let's take a look at one more neat feature of FIX. Again type FIX ECHOLN WOW!. From the command mode, hit an ESCape to enter "run" mode. Now with the DOWN ARROW, slowly hit this key until you reach the TTYL command. Stop at this point. The next process should remind you quite a bit about VUE. The cursor should be resting by the TTYL command. Hit a control-p. The TTYL command should be in dim output now. What you have done is set a "breakpoint" within FIX at the instruction TTYL. With the UP ARROW, move the cursor back to the top of the screen. With this breakpoint set, ECHOLN is set up to "run" until it hits a breakpoint. The way in which you make ECHOLN run is to hit a control-x. Hit a control-x at this time. The cursor should "immediately" move to the break point, TTYL. At this time hit a return. WOW! How about that. You just made ECHOLN "speed read" all lines up to the breakpoint, and then from the breakpoint you then slowly examined the actions of ECHOLN. Setting breakpoints helps you to debug your programs faster by allowing you to speed by the "good" code and examine at length the code that needs to be looked at more closely. By the way, you can have 10 breakpoints set up within any one file. Playing with FIX This short example session with FIX by no means shows you the complete set of instructions FIX understands. You should play around with FIX. One suggestion would be to FIX ECHOLN with no line input and notice the error handling process. Feel free to "toggle" back and forth between command mode and execution mode within FIX to examine how the registers respond to the commands. I suggest that you read the AlphaFIX User's Manual to fully understand FIX and its functions. Use FIX when you have created your own .LIT file and for some reason your new program doesn't work. Also, practice with other short programs from the Assylum. It really helps to FIX a program that you completely understand when you are trying to learn more about FIX. After a few practice sessions with FIX, you will better learn exactly how AMOS works from a hardware point of view. Now if only the Alpha could FIX dinner! .