Guide to Using LC3Tools
(based on ’s guide) The University of Texas at 2020 © McGraw-Hill Education. All rights reserved. No reproduction or distribution without the prior written consent of McGraw-Hill Education.
Copyright By cscodehelp代写 加微信 cscodehelp
The LC-3 is a piece of hardware, so you might be wondering why we need a simulator. The reason is that the LC-3 doesn’t actually exist (though it might one day). Right now it’s just a plan – an ISA and a microarchitecture which would implement that ISA. The simulator lets us watch what would happen in the registers and memory of a “real” LC-3 during the execution of a program.
How this guide is arranged
The first section gives you a quick introduction to the interface.
The second chapter walks you through entering your first program, in machine language, into the text editor. You’ll also find information about writing assembly language programs, but you’ll probably skip that part until you’ve learned the LC-3 assembly language later in the semester. The third section shows you how to watch the effects of the program you just wrote in the simulator.
The fourth section takes you through a couple of examples of debugging in the simulator. In other words,
Chapter 1 Chapter 2 Chapter 3 Chapter 4
What you see on the screen 3 Creating a program for the simulator
Running a program in the simulator
Debugging programs in the simulator
Chapter 1: What you see on the screen
This chapter just provides a brief reference to the different parts of LC3Tools. As you continue through the chapters, the usage of each of the buttons and panels will become clearer.
When you launch LC3Tools, you see this.
The main panel in the center of the screen is the text editor. This is where you type out binary or assembly programs. The name of the file being edited is at the top.
Below the text editor is the console, which shows messages about the Assembly or Conversion process. When you first open LC3Tools, nothing will be displayed.
The panel to the left contains the following buttons from top to bottom:
1. Create a new file
2. Save a file
3. Open an existing file
4. Assemble an .asm file or convert a .bin file into an .obj file
The toolbar at the top allows you to change the theme and privilege mode. The privilege mode is only relevant to the simulator section, and it will be addressed in chapter 4.
Finally, the top right of the screen allows you to switch between the editor and the simulator tabs.
Clicking on the simulator button pulls up the following display, which has quite a bit more going on. Let’s break it down.
The panel on the top half of the left side shows the register values in hex and decimal. This panel also shows the Processor Status Register (PSR) and Condition Codes (CC), the Program Counter (PC), and the Machine Control Register (MCR).
The panel below the registers is the console. The console is used for I/O operations. Click the console box to begin sending in keyboard input. When selected, the console will have a glowing blue border around it. Program output will be displayed whether the console is in focus or not. The button in the top right will clear all the program output.
The right half of the screen is the memory panel. Each entry shows the following information from left to right: a stop sign indicating whether or not a breakpoint is set at that location (currently there is a breakpoint set at x0201), the location of the PC (currently at location x0200), the memory address, the hex and decimal values at the memory location, and the string from the binary or assembly file source code corresponding to the memory location.
The bottom of the memory panel allows you to navigate memory. The leftmost entry lets you jump to a specific spot in memory. The PC button will show the memory starting at the current PC. The arrow buttons allow you to scroll through memory. The large buttons jump by an entire snippet of memory at a time, and the small buttons jump by 5 locations at a time.
Finally, the toolbar on the left contains the following buttons from top to bottom:
1. Open an .obj file
2. Begin simulating
3. Reload object files
4. Step over an instruction
5. Step in an instruction
6. Step out of an instruction
7. Reinitialize the machine
8. Randomize the machine
More details on the specifics of these buttons can be found in chapter 4.
Chapter 2: Creating a program for the simulator
The Problem Statement
Our goal is to take the ten numbers which are stored in memory locations x3100 through x3109, and add them together, leaving the result in register 1.
Entering your program in machine language
You have the option to type your program into LC3Tools in either binary or the LC-3 assembly language. Here’s what our little program looks like in binary:
When you type this into LC3Tools, you’ll probably be looking at a chart which tells you the format of each instruction, such as the one inside the back cover of the textbook. It may be easier for you to read your own code if you leave spaces between the different sections of each instruction. Also, you may put a semicolon followed by a comment after any line of code, which will make it simpler for you to remember what you were trying to do. In that case your binary would look like this:
0011 0000 0000
0101 001 001 1
0101 100 100 1
0001 100 100 1
1110 010 011111100
0110 011 010 000000
0001 010 010 1 00001
0001 001 001 0 00 011
0001 100 100 111111
0000 001 111111011
1111 0000 00100101
; start the program at location x3000
; clear R1, to be used for returning the sum
; clear R4, to be used as a counter
; load R4 with #10, the number of times to add
; load the starting address of the data
; load the next number to be added
; increment the pointer
; add the next number to the running sum
; decrement the counter
; do it again if the counter is not yet zero
Either way is fine with LC3Tools. It ignores spaces anyway. The second way will just be easier for you to read.
Saving your program
Click on the Save button in the toolbar on the left. You probably want to make a new folder to save into, because you’ll be creating more files in the same place when you turn your program into an object file. Call your program addnums.bin.
Creating the .obj file for your program
Before the simulator can run your program, you need to convert the program to a language that the LC-3 simulator can understand. The simulator doesn’t understand the ASCII representations of binary that you just typed into LC3Tools. It only understands true binary, so you need to convert your program to actual binary, and save it in a file called addnums.obj.
When you press the Convert button in the toolbar on the left, the addnums.bin file will try to be converted into a real binary file, addnums.obj. The console at the bottom of the window will report whether the conversion was a success or if there were any errors.
If you don’t know the LC-3 assembly language yet, now you’re ready to skip ahead to Chapter 3, and learn about the simulator. Once you do learn the assembly language, a little bit later in the
semester, you can finish Chapter 1 and learn about the details of entering your program in a much more readable way.
Chapter 3: Running a program in the simulator
Now you’re ready to run your program from the previous chapter in the simulator. Click on the
simulator tab and then press the Open button. Browse to and select addnums.obj. Assuming you originally wrote the assembly version of the program, this is what you will see in the memory panel.
Notice that the first line of your program, no matter what format you originally used, is gone. That line specified where the program should be loaded in memory: x3000. As you can see if you scroll up a line or so, the locations before x3000 are still all 0s.
Since nothing has happened yet (you haven’t started running or stepping through your program), the temporary registers (R0 through R7) still contain all 0s, and the PC is pointing to the first line of your program (as is the blue arrow). Bit 15 of the PSR is 1, which means the machine is in user mode. Bit 15 of the MCR is set, which means the machine is powered on.
Loading the data (ten numbers) into memory
There are multiple ways to get the data into locations x3100 to x3109, and we show one of them below.
Method 1: Manually entering values
To add numbers to locations x3100 to x3109, type x3100 into the ‘Jump to Location’ text box and press enter. The memory panel will jump to location x3100.
Click on either the hex value or the decimal value and a text box will pop up. You may enter a hex value or decimal value, respectively, to set the memory location.
Continue doing so until locations x3100 through x310A have been set as such:
Running your program
Type x3000 into the ‘Jump to Location’ text box and press enter. Click the gray arrow to the left of location x3000 to set the PC to that location (it may already be set correctly there). Click the gray stop sign to the left of location x3009 to set a breakpoint at this location. Breakpoints will be discussed in further detail in Chapter 4, but basically simulation will pause as soon as the PC encounters a breakpoint. By setting a breakpoint at the HALT instruction, the simulator will pause before entering the HALT trap service routine. This is important because the HALT trap service routine changes R1, which means if it executes we’ll never actually see the sum in R1!
The memory panel should look like this:
Press the Run button. Simulation will pause as soon as the PC encounters location x3009.
If you’ve already added up the ten numbers you put into the data section of your program, you know that 55 is the answer to expect. That’s what you should see in R1 when the program stops at the breakpoint (in hex, the result is x0037).
Stepping through your program
Now that you’ve seen your program run, you know it works. But that doesn’t give you a good sense for what’s actually going on in the LC-3 during the execution of each instruction. It’s much more interesting to step through the program line by line, and see what happens. You’ll need to do this quite a bit to debug less perfect code, so let’s try it.
First, you need to reset the very important PC to the first location of your program. Set the PC back to x3000 by clicking the gray arrow to the left of location x3000. Alternatively, you can change the value of the PC by clicking either the hex or decimal value in the register panel. Now you’re ready to step through your program.
Click the Step Over button. A couple of interesting things just happened:
1. R1 got cleared (you won’t notice a difference if it was already set to 0).
2. The blue arrow representing the PC moved to location x3001.
Click the Step Over button again. Now R4 got cleared (you won’t notice a difference if it was already set to 0) and the PC moved to location x3002.
Click the Step Over button again. Now R4 got set to 10 and the PC moved to location x3003.
Continue to step through your program, watching the results of each instruction, and making sure they are what you expect them to be.
At any point, if you “get the idea” and want your program to finish executing in a hurry, click on
the Run button, and that will cause your program to execute until it reaches the breakpoint you set on the HALT.
Now you know how it feels to write a program perfectly the very first time, and see it run successfully. Savor this moment, because usually it’s not so easy to attain. But maybe programming wouldn’t be as fun if you always got it right immediately. Let’s pretend we didn’t. The next chapter will walk you through debugging some programs in the simulator.
Chapter 4: Debugging programs in the simulator
Now that you’ve experienced the ideal situation of seeing a program work perfectly the first time, you’re ready for a more realistic challenge – realizing that a program has a problem and trying to track down that problem and fix it.
The following are a series of steps that are common while debugging any program, but we will work with a single example so it is easier to follow along.
Example 1: Debugging a program to multiply without a multiply instruction The Problem Statement
Our goal is to multiply the values in R4 and R5 and store the result in R2.
Entering your program in machine language
Enter the following program into the editor.
0011 0010 0000 0000 0101 010 010 1 00000 0001010010000100 0001 101 101 1 11111 0000 011 111111101 1111 0000 00100101
; start the program at x3200
; clear R2
; subtract 1 from R5, put result in R5
; branch to location x3201 if zero or positive ; halt
As you can tell by studying this program, the contents of R4 and R5 will be “multiplied” by adding the value in R4 to itself some number of times, specified by the contents of R5. For instance, if R4 contains the value 7, and R5 contains the value 6, we want to add 0+7 the first time through, then 7+7 the second time through, then 14+7 the third time through, then …, then 35+7 the sixth time through, ending up with the value 42 in R2 when the program finishes.
Click on the Save button and call the file multiply.bin. Press the Convert button in the toolbar on the left to create multiply.obj.
Loading the program in the simulator
Switch to the simulator tab and click the Open button. Browse to multiply.obj and open it.
Setting a breakpoint at the halt instruction
Breakpoints are extremely useful in many ways, and we’ll get to a few of those soon. You should make it a habit to set a breakpoint on your “halt” line, because if you run your program without that, you’ll end up in the halt subroutine which will change some of your registers before halting the machine. So first, set a breakpoint on line x3204 by clicking the gray stop sign to the left of the address.
Running the buggy multiply program
Before you run your program for the first time, you need to put some values in R4 and R5 so that they’ll be multiplied (or not, in this case!). How should you choose values to test? Common sense will help you here. 0 and 1 are probably bad choices to start with, since they’ll be rather boring. It would be good to test those later though. If you choose a large number for R5, you’ll have to watch the loop repeat that large number of times. Let’s start with two reasonably small, but different numbers, like 5 and 3.
Click on the decimal value to the right of R4 in the register panel. Type in 5 in the text box that pops up and press enter. Do the same for R5, except enter in 3.
Ensure that the value of the PC is x3200. This can be confirmed by checking the PC register in the register panel or by seeing if there is a blue arrow to the left of location x3200 in the memory panel.
Run your program by pressing the Run button. When the PC hits the breakpoint, R2 should contain the value 15. However, R2 contains 20! Something went wrong.
Stepping through the multiply program
One option for debugging your program is to step through the entire multiply program from beginning to end. Since you have a loop, let’s approach debugging a different way. First, let’s try stepping through one iteration of the loop to make sure that each instruction does what you think it should.
To begin simulating again, you need to reset a couple of things. Click the gray arrow to the left of location x3200 in the memory panel to set the PC back to the beginning of the program. Click the decimal value to the right of R5 in the register panel and set the value to 3 again.
Click the Step Over button. The PC changes to x3201 and R2 is set to 0. This is what you expected the first instruction to do, so you can move on to the next instruction.
Click the Step Over button. Now PC contains x3202 and R2 contains the value 5. Again, this is what you want, so keep going.
The next time you click the Step Over button, R5 changes from 3 to 2 (I’m not going to keep mentioning the PC, but you’ll notice it changing after each instruction as well). R5 has a double purpose in this program. It is one of the numbers to multiply, but it is also your “counter” – it tells you how many more repetitions of the loop are left to go. Each time through the loop, R5 gets decremented. That seemed to happen just fine, so keep going.
Clicking the Step Over button once more cause the branch instruction to execute. When a branch instruction executes, one of two things can happen. Either the branch gets taken, or it doesn’t get taken. In this case, the branch got taken. Why? Because the branch tested the condition codes which were set by the add instruction right before it. The result of the add was 2, a positive number, so the P condition code was set to 1. Your branch is taken if the Z condition code or the P condition code contains a 1. The branch was executed taken, so the PC now points to x3201, and you’re ready for another iteration of the loop.
Stepping through the program for one repetition of the loop has shown that there’s nothing wrong with any of the individual instructions in the loop. Maybe the problem lies in the way the loop is set up instead, so let’s try another approach.
Debugging the loop with a breakpoint
One good technique for discovering whether a loop is being executed too many times is to put a breakpoint at the branch instruction. That way, you can pause once at the end of each iteration, and check out the state of various registers (and memory locations, in more complicated programs).
Set an additional breakpoint at the branch at location x3203 by clicking the gray stop sign to the left of the address. Now there should be breakpoints at both x3203 and the HALT at x3204. Simulation will pause if the PC encounters either breakpoint.
Run the program by clicking the Run button. Notice the register values when you hit the breakpoint. R4 is unchanged, it still contains 5. R5 has changed to 2. The condition code is set to P. This tells you that the branch will be taken.
Click the Run button again and look at the registers. R4 is unchanged, R5 contains 1, and R2 contains 10. The condition code is set to P, so the branch will be taken.
Click the Run button again and look at the registers. R4 is unchanged, R5 is now 0, and R2 contains 15. The condition code is set to Z, so the branch will be taken. At this point the program should stop, but we’re going to take the branch again and do an extra, unwanted iteration of the loop. That’s the bug.
By changing the branch instruction to only be taken when the condition code is set to P, the loop will happen the correct number of times. To prove this to yourself, you can edit the program in the editor tab by changing the line with the branch to:
0000 001 111111101 ; branch to location x3201 result is positive
saving, converting to .obj format, and reloading the new version into the simulator by pressing
the Reload Object Files button. Alternatively, if you don’t want to change the source code yet in case you find more bugs later, you can directly change the instruction in the simulator by clicking on the hex value next to address x3203 in the memory panel. Enter x0201 (it should be x0601 currently) in the text box that pops up and press enter. Remember that the next time you load multiply.obj, the bug will still be there unless you go back and fix the original binary version of the program and reconvert it.
Now set the PC to x3200 once again and change R5 to contain 3. Click the red stop sign at location x3203 to disable the breakpoint. Click the Run button and you should see the value 15 in R2. Congratulations – you’ve successfully debugged the program!
Other debugging tools
Here’s a description of the debugg
程序代写 CS代考 加微信: cscodehelp QQ: 2235208643 Email: firstname.lastname@example.org