This lab is about familiarizing you with the MARS MIPS simulator software, and getting you started on your FUN ASSEMBLY LANGUAGE JOURNEY. Well I think it’s fun.
I write my labs and projects like tutorials. There’s a lot of reading, but that’s because you’re new to all these things and I have to explain everything. Just follow the directions in order and you’ll be done in no time.
Try this: these boxes are things to play around with and learn a little more. They are not required and you don’t have to turn in the code you write for these, so you can erase that code when you’re done playing around.
PAY ATTENTION to these colored boxes.
1. Getting started
You must use the modified version of MARS available on the software page.
Once you download that
jar file, put it somewhere convenient. Do not just run things from Chrome’s download bar or from your “recent files” every time. That is not a sustainable way of using your computer. If you don’t know where files “go” when you download them, or how files and folders are arranged on your computer, please ask me for help with that.
Once you successfully start it, you will see this:
Setting things up (important!)
In the Settings menu, make sure the following things are checked (enabled):
- ✔ Show Labels Window (symbol table)
- ✔ Clear Run I/O upon assembling
- ✔ Initialize Program Counter to global ‘main’ if defined
Leave the other settings unchanged.
Also, if the registers view on the right side is enormous and taking up half the window, you don’t have to live like that. Just resize it by dragging the vertical divider so it’s narrower.
A brief but very important interlude for Mac users only
It seems like every year Apple does something to make the lives of Java users harder. If you are using a Mac, you may run into issues.
Once you get MARS running, go to “File > Open…”. You will see a file chooser dialog pop up. You should be able to see files in there, and if you drop down the folder list, you should see your folders, your home directory, etc. like this:
If, however, you see no files no matter which directory you choose, follow the steps in this video and restart MARS. It should be fixed, but if not, contact me. You can’t really do any work until this is fixed.
2. Hello, nothing
Now you’ll learn how to make an empty program, assemble it, and run it.
Make a new file, and save it with the name
usernameis your username. (I would put
You have to save the file in order to assemble it!
In MIPS, comments start with a
#sign. At the top of the file, put your name and username in a comment.
Just like in Java or C, our assembly programs start at a
mainfunction. Type these lines into your file.
.globaldirective is only needed for
main. Most of your functions won’t need it.
.global main main:
main:is a label. Labels name parts of your code; not just functions, but also loops, if-elses, variables, etc.
Instead of “compiling,” we “assemble” an asm program. When you assemble the program with , it’ll switch to the Execute tab.
If you cannot see these panels and just see a blue void, let me know. It’s a silly issue but it’s easy to fix.
Now run with . In the “Run I/O” at the bottom of the screen, it’ll say
-- program is finished running (dropped off bottom) --
It’s a completely empty program that does nothing. Yay!
Try this: what error do you get if you remove the
.global main line? Well now you know what to do if you see that error. :)
3. Playing with registers
Now you’ll learn how to put integers into registers and copy them around, and also to step through your program one instruction at a time.
Look at the register pane on the right side of the window. There are 35 registers listed, and all but
sp contain 0. These are the values they are set to when your program starts.
“Immediate” means “a constant that is written inside the instruction.”
Type these instructions in after your
listands for “load immediate”, and it puts a constant value into a register.
li t0, 1 li t1, 2 li t2, 3
By analogy to Java,
li t0, 1is like doing
t0 = 1.
Assemble and run. Those
t0, t1, t2registers on the right side changed to 1, 2, and 3!
But it was too fast to see what happened. Assemble again, but this time, step through instruction-by-instruction with this button: . Watch the values of the registers and the highlighted instruction in the text window.
- You’ll see the registers highlighted green when they change.
- You’ll notice that the highlighted instruction is the one that is just about to run.
But wait! You can go backwards too. Use this button: .
- You’ll see the instructions happen in reverse, and the registers will get set back to 0.
Stepping forward and backward one instruction at a time is extremely helpful when you first learn to program assembly. (It’s extremely helpful even when you’ve been using it for years, too.)
Half a century ago, someone decided to use the word “move” instead of “copy” and now we’re stuck with it. Sorry!
Last, we can copy values between registers with the
moveinstruction. After your
lis, write these lines:
move a0, t0 move v0, t1 move t2, zero
- Assemble and step through. The values are copied from the register on the right into the register on the left. This is important: data is never “moved” on a computer, always copied. (What would moving it even do? What would be left in the original register? I dunno.)
A really, really common mistake is to read
move a0, t0as “move
t0”. This is backwards. Try to imagine
move a0, t0as
a0 = t0instead.
Try this: Load a hexadecimal immediate into a register, like
li t0, 0xF00D. Assemble, and look at the “Code” column in the text segment. Do you see it?
Now try putting a value into the
zero register. That’s its name.
li zero, 10. What happens when that runs? What value is still in it? Why do you think the register is named
zero then? ;o
When you step through your program, one other register changes on every instruction… step back, too. What register is that? What do you notice about its value?
A note on formatting your code
This applies to any language, not just assembly: do not treat code formatting as a “final step” you do to “clean things up” before submitting. It is not. Code formatting is absolutely crucial for making your code readable and understandable. Keep your code formatted nicely while you write it, not at the end.
Go to the Materials page and look for the “MIPS style guide” in the References. Have a look at the code comparisons in particular. Here is an important rule about dealing with indentation, in any programming language:
Never use the spacebar at the beginning of a line of code to “line things up.” That is what the Tab key is for.
The Tab key is what you use to indent code. You can also deindent code with Shift+Tab. Finally, you can select several lines of code and use Tab and Shift+Tab to indent and deindent them in virtually any code editor, including MARS.
Knowing all this, format and comment the code you’ve written so far so that it looks like this:
I have my editor settings (Settings > Editor) set a little different from the defaults. If your colors are different or your tabs are wider than the screenshot, that’s fine. Consistency and neatness are the most important parts of code formatting.
4. Printing things
Normally the first program you’d write in a language is “hello world” but that’s a bit too complicated for right now. Instead, let’s settle for printing some integers.
After all the code from above, type this:
# print 123 li a0, 123 li v0, 1 syscall
Assemble and run, and you’ll see the number
123printed in the “Run I/O”.
What’s going on here? What is
a0? What is
v0? What is
As you’ll find out in 449, programs have to ask the operating system to get input or produce output, and we do that with system calls. MARS pretends like it’s a tiny operating system, so it has many built-in system calls to print things out, ask the user to type something, etc.
We choose which system call to run by putting a number into the
v0 register before executing the
From now on, I want you to treat the
li v0, whatever and
syscall as two halves of the same thing. You do not put any code between the
li v0, whatever and the
syscall. They go together. Never use
syscall without first doing
li v0, whatever.
In MARS, go to the “Help > Help” menu item. Then click “Syscalls” on the lower set of tabs. This tells you about what syscalls are, which ones are available, what their numbers are, and their arguments and return values.
Notice it says this at the top of the table:
There are lots of other possible values you can put into
v0 to choose different syscalls, but syscall 1 means “print an integer.”
Then, the arguments to the syscalls go in the
a registers. That’s why they are named
a is for argument.
So to sum up: the three lines above correspond roughly to this Java code:
5. Printing more numbers and newlines
Don’t forget to keep commenting your code so you can tell what it does!
Right now, your program just prints out 123. Now:
- Add code to do the equivalent of
System.out.print(456)after the first print. (It will be another 3 lines.)
- Run it and look at the output.
It comes out as
123456. Well, that’s confusing! But that’s because you printed both numbers on the same line. Unfortunately there is no equivalent of
System.out.println. So, we have to print the newline ourselves.
- Between the two prints (right after the first
syscall), we are going to do another syscall:
- for the argument
'\n'(that’s single quotes around a backslash and
- for the syscall number
11(look up what syscall
11does in the MARS help)
- for the argument
- Run it again.
You should now have
123 and then
456 on another line after it. Nice!
Try this: see if you can use syscall 11 to print out a short message by using different characters as arguments (
a0). It gets pretty repetitive, doesn’t it? Don’t worry, there are easier ways to print strings :)
6. Exiting gracefully
Finally, you’ll learn how to exit your program more “properly”.
At the end of your
main function (so, the end of your program), use the exit syscall (number 10). It takes no arguments, so you don’t have to put anything in the
When you run now, your output should now look like:
123 456 -- program is finished running --
So, the final message changed. It might not seem that important now, but it’ll save you a lot of trouble later if you end every
main function with the exit syscall.
- On Canvas, go to “Assignments” and click Lab 1.
- Click “Start Assignment.”
- Under “File Upload,” click the “Browse” button and choose your
- Click “Submit Assignment.”
If you need to resubmit, that’s fine, just click “New Attempt” on the assignment page and upload it again.