-
Notifications
You must be signed in to change notification settings - Fork 55
One Page Tutor for MIPS
Now suppose you have a file with this very simple MIPS code in it:
.data
theString:
.space 64
.text
main:
li $v0, 8
la $a0, theString
li $a1, 64
syscall
jr $ra
I'll go through it line by line.
The first line ".data" tells SPIM that what follows will be data.
".space 64" then sets aside 64 bytes for use of whatever purpose we want, the first byte of which may be referenced by the label "theString:", which appears on the line before.
".text" then tells the computer that what follows will be actual code.
"main:" is our requisite main label that symbolizes the start of the program.
The next three lines of "la" and "li" statements set registers to appropriate values before we say "syscall". This is where you should take look at the table at the top of A-49. Find the "read_string" line, and then read the rest of this. I provide a line of the code, and then some background.
li $v0, 8
When you call "syscall" in your code, a value called the "system call code" will determine what function syscall performs. The "system call code" is stored in the register $v0. The system call code for reading a string is 8, so I stored the number 8 into register $v0 using "li".
la $a0, theString
If you look at the "arguments" column in this table, it says "$a0 = buffer, $a1 = length". What this means is that the $a0 register must be set to the location in memory to which the computer will record the input. This is accomplished by loading the address (la) of theString into $a0.
li $a1, 64
The second part of the arguments entry in the table says "$a1 = length", which you set to the maximum number of characters that should be read in. I chose 64 characters. You can have it be 50, or 200, or 37, or whatever you like, but you shouldn't go above 64 (in this example) because in the first part of this program you only set aside 64 bytes using the ".space" directive. Note that this space set aside includes the terminating null '\0' character, so it will actually read only up to 63 characters from the buffer when the syscall executes.
syscall
At long last, having set your argument ($a0, $a1) registers and your call code register ($v0), you call syscall. Upon receiving the syscall command, the system says, "what do I need to do?" and sees that $v0 == 8. It now knows to read in a line from the SPIM console, and to write the input to the memory location referenced by $a0 (which was set to theString), for a string of maximum length of $a1 (which we set to 64).
It reads input until it encounters a '\n' character or reaches the maximum number of characters it can reach (which we stored in $a1 as 64), and stores that input (including the '\n' character) into a string null-terminated with a '\0'. Notice that the maximum length of the string includes the '\0' terminating null character.
jr $ra
This jump-returns to the return address in the $ra register.
If you run this program and type this in:
Hello!
...and hit return, the memory in the computer at the point referenced by theString will look like the following. Each block represents a byte in data. The blocks are adjacent, and so are the bytes in memory. The byte holds the ASCII value for the character I display. The first byte is the byte referenced by "theString", and the string is termined by a null character.
H e l l o ! \n \0
After syscall is finished, the byte referenced by "theString" would contain the ascii value for 'H', the next byte would contain 'e', etc, etc.
More info refer to http://www.tfinley.net/notes/cps104/mips.html