Tom Kelliher, CS26
Sept. 12, 1996
For a discussion of RISC assembly languages, I'm going to substitute the MIPS processor for the PowerPC. Don't read the PowerPC section of Chapter 2. I do expect you to read the sections on the Motorola 68000.
Resources for the MIPS:
Additionally, the Postscript file is stored in
~kelliher/pub/cs26/spim.ps. If you are running X, you can use
ghostview to display the documentation. The following command can be
used to print the file:
lpr -Pps ~kelliher/pub/cs26/spim.psPlease bear in mind that if you print the document to use it just one time, you're really wasting 25 sheets of paper.
You need to understand section 2.7, Stacks & Queues to understand this material.
We know how to implement loops and the sundry ``decision'' statements, how do we implement function linkages?
At a high level (that of C++ or Pascal), what is going on with a function call?
void f(void)
{
...
g();
...
}
void g(void)
{
...
return;
}
void h(void)
{
...
g();
...
}
Can we use branch instructions to do this?
Add a link register to the CPU and 2 instructions:
Call_subroutine
Return_from_subroutine
subr_f: move R0, R1
Call_subroutine subr_g
move R1, R0
Return_from_subroutine
subr_g: add #1, R1
Return_from_subroutine
subr_h: move R3, R1
Call_subroutine subr_g
move R1, R3
Return_from_subroutine
What would happen if f() called g() called h()?
What about recursion?
A stack can be used to store just return values; a stack frame is a more general mechanism.
Standard method for allocating a function's variables.
Consider a function:
void f(void)
{
int i, j;
float x;
struct S s;
...
}
What must the stack frame provide storage for?
Why can't I just keep the variables in registers?
What about arrays?
What about global variables and static locals?
Suppose:
How are parameters transmitted from caller to callee?
What about return values?
Consider:
void f(void)
{
int i = 12;
float x = 34.56, y;
y = g(i, &x);
}
float g(int a, float* z)
{
char c;
*z += 2.0;
return a + z;
}
Example SPIM program:
# addn.spim
# Input: A number of inputs, n, and n integers.
# Output: The sum of the n inputs.
.data # Constants.
prmpt1: .asciiz "How many inputs? "
prmpt2: .asciiz "Next input: "
sum: .asciiz "The sum is "
nl: .asciiz "\n"
.text # Main.
.globl main
main: li $v0, 4 # Syscall to print prompt string.
la $a0, prmpt1
syscall
li $v0, 5 # Syscall to read an integer.
syscall
move $t0, $v0 # n stored in $t0.
li $t1, 0 # sum stored in $t1.
while: blez $t0, endwhile
li $v0, 4
la $a0, prmpt2
syscall
li $v0, 5
syscall
add $t1, $t1, $v0 # Increase sum by new input.
sub $t0, $t0, 1 # Decrement n.
b while
endwhile: li $v0, 4
la $a0, sum
syscall
move $a0, $t1 # Syscall to print an integer.
li $v0, 1
syscall
li $v0, 4
la $a0, nl
syscall
li $v0, 10 # Syscall to exit.
syscall
An example SPIM run:
abacus:~/Class/Cs26/Examples % spim SPIM Version 5.3 of Aug 30, 1993 Copyright 1990-92 by James R. Larus (larus@cs.wisc.edu). All Rights Reserved. See the file README a full copyright notice. (spim) load "addn.spim" (spim) run How many inputs? 5 Next input: 1 Next input: 3 Next input: -20 Next input: 45 Next input: -6 The sum is 23 (spim) quit abacus:~/Class/Cs26/Examples %