CPSC 220, Fall 2018
Lab 2: Machine Language Programming
Over the next three lab periods, you will be working on two projects. For the first project, you will write several programs in Larc machine language. For the second project, you will work on a functional Larc simulator written in Java. The first of these projects in due in two weeks, and the second will be due in three weeks. The second project will be specified in next week's lab handout.
For this lab, you will write several machine language programs for the Larc computer. These are programs that would be trivial to write in Java. Working in machine language, however, they are not at all trivial. I suggest that for each problem, you should first write out a solution in pseudocode. You should work on the pseudocode to get something that corresponds closely to the Larc machine language. For example, an assignment statement such as Y=2*Y+7 will require the use of several machine language instructions and several registers. You might want to write the program using something like Larc assembly as a step along the way.
You should make a folder named lab2 in your homework directory. Your machine language programs should be placed in that lab2 folder by the beginning of lab in two weeks, on September 20. Put your name in a comment at the top of each program. You should give the programs identifiable names, such as ex1.out, ex2.out., etc.
Some Setup
The directory /classes/cs220/larc contains some files related to Larc, including a copy of the "3*N+1" example that we looked at in class on Wednesday. Three of the files are programs that you can use in this lab. One of the programs, sim, is a Larc simulator that you can use to execute the ML programs that you write. It was written by Marc Corliss long ago. It is a compiled Linux program, and it will only run on Linux. The second program is a Larc debugger, also written by Marc Corliss. It was written in Java and comes as a .jar file. It is fairly easy to use and was demonstrated in class. (You can read more about it, if you want more information, in Chapter 4 in the complete Larc manual.) There is also a short Java utility program, String2Larc, that translates strings of characters into the form that is required for a Larc ML program.
It will be useful to have "aliases" (shortcuts) for running these program. You can define aliases in your .bashrc file, which is executed every time you log in remotely or open a Terminal window. Edit your .bashrc file, for example by giving the command
xed .bashrc
while you are working in your home directory. Copy-and-paste the following the lines to the end of the .bashrc file, and save the file:
alias sim='/classes/cs220/larc/sim' alias db='java -jar /classes/cs220/larc/db.jar' alias s2l='java -cp /classes/cs220/larc String2Larc'
This defines the command sim to be a command that you can use in a Terminal to mean the same thing as /classes/cs220/larc/bin/sim, and similarly for the other aliases. (The .bashrc file is applied when a Terminal is opened, so it won't apply to the one that you use to edit .bashrc; you have to open a new Terminal to use the aliases.)
Writing and Running Machine Language Programs
You should have read about the format of Larc machine language programs in Chapter 3 of the Larc manual, which was handed out in class. In reality, you are just going to write each program as a plain text file. You will then run that file through a program that simulates the Larc computer. You should understand that the files that you create are not really machine language. A real machine language program would not be human readable, and it would contain just 16 bits (two bytes) for each instruction.
Every line in the machine language files that you create must contain one of four things:
- Exactly 16 0's and 1's, representing a 16-bit binary number
- 0x followed by exactly 4 hexadecimal digits, representing a 16-bit binary number
- A blank line, which is ignored
- A comment line, starting with #, which is ignored.
Each program should include a comment at the top, giving your name. It should use blank lines to break up the program into functional parts, and you should include comments to say what each part does. (For example, a comment like "# Read a string and store it at location 3C" to explain the machine language instructions that you need to carry out that command.)
The name of a file that contains a Larc machine language program should end with ".out", and it must end with .out if you are going to use the debugger on it. To run a machine language file named myprog.out, you can use the command
sim myprog.out
and you can load the same program into the debugger with the command
db myprog.out
This assumes that you have set up the aliases, as discussed above.
Programming Assignments
The assignment is to write some machine language programs for Larc. This can be a very painful experience. To make it less painful, I suggest starting with a comment for each short task that you want to do, then filling in the instructions for each task. The big problem is finding the addresses of strings and places you want to jump to. Here are two approaches to dealing with that problem. One is to leave all the addresses set to, say, FF, at first. Then apply the debugger, db, to the program. In the panel at the right, you see your code with a hexadecimal address for each memory location. It should be easy to find your strings and look up their addresses. Conditional branches are harder, since you need the number of memory locations between the instruction that follows tha branch instruction and the place to which you want to branch. Another possibility, which might look like a cheat at first but is still OK, is to put a branch instruction at the start of the program, followed by the strings. The branch instruction should jump past the strings to the first instructions in the actual program. Assuming that you have line numbering turned on in your editor, you should be able to use the line numbers to figure out the addresses of the start of each string. One idea that I strongly discourage is to try to write the program without comments, with the idea of getting addresses from line numbers. I know from experience that it is very difficult to write the code without the comments. Note that a real problem is if you have to add or remove instructions from your code, since that might force you to adjust the addresses that appear in your program. So, try to get the code right the first time.
- Write a program that computes and outputs the value of the expression 6*15-100 and then halts. The program must do the calculation using several machine language instructions. The purpose of this exercise is is to make sure that you can write and run a simple program. There are no branches in the program, and just two system calls. (Don't forget that a program should end with a "Halt" syscall.)
- Write a program that gets two numbers from the user, then computes and prints their sum and their product. The program must ask the user to enter each number by saying, for example, "Enter a number". It must label the output by saying, for example, "The sum is 17" and "The product is 60". There must be a new-line at the end of each line of the output. The purpose of this exercise is mainly to use system calls to do input and output. You will have to convert the strings that you want to use in the output into binary numbers, before you can include them in the program. If you have set up the aliases as instructed above, you can use the command s2l to do that. ("s2l" stands for "string to larc", and the third character is a lower case "L".)
- Write a program that gets two numbers from the user, then prints the smaller of the two numbers. Include prompts to ask the user for each input, and include some text in the output to label the output. (You could write the program by modifying a copy of your solution to the previous exercise.) The main point of the exercise is make a test and use a branch instruction.
- Write a program that reads a string from the user and then outputs a reversed copy of the string. For example, if the input string is "Hello World", then the output should be "dlroW olleH". The purpose of this exercise is to use a loop. (You can either output the reversed string character by character, or you can make a reversed copy in memory and output that.)
- Write a program that reads a sequence of non-zero integers from the user. Stop inputting numbers when the use enters a zero. Then, print the count of the input numbers and the sum of the input numbers. (Note that it is not necessary to store the numbers in memory.)
If you get bored, you can write one additional program to maybe get a little extra credit.