Procedure Calls
Procedure Calls
Procedure Calls
Agosto 2013
Tek
Procedure Calls
Definitions
Caller/Callee Duties
• Caller: • Callee:
– passes arguments to – performs the
callee. procedure
– jumps to the callee – returns the result to
caller
– returns to the point
of call
– must not overwrite
registers or memory
needed by the caller
jal <address> # $ra = PC + 4
# PC = <address>
• MIPS reserves register $31, a.k.a. $ra, to store the return address.
• The called procedure must place the return value (if any) somewhere
from which the caller can retrieve it. The convention is that registers
$v0 and $v1 can be used to hold the return value. We will discuss what
to do if the return value exceeds 8 bytes later…
jr $ra # PC = $ra
Procedure Calls
Passing Parameters
$a0 # 1st parameter
$a1 # 2nd parameter
$a2 # 3rd parameter
$a3 # 4th parameter
• The called procedure can then access the parameters by following the same
convention.
• What if there are more than four parameters? We'll discuss that later…
Procedure Calls
# $s0 = result
diffofsums:
addi $sp, $sp, -12 # make space on stack to store 3 registers
sw $s0, 8($sp) # save $s0 on stack
sw $t0, 4($sp) # save $t0 on stack
sw $t1, 0($sp) # save $t1 on stack
add $t0, $a0, $a1 # $t0 = a + b
add $t1, $a2, $a3 # $t1 = c + d
sub $s0, $t0, $t1 # result = (a + b) - (c + d)
add $v0, $s0, $0 # put return value in $v0
lw $t1, 0($sp) # restore $t1 from stack
lw $t0, 4($sp) # restore $t0 from stack
lw $s0, 8($sp) # restore $s0 from stack
addi $sp, $sp, 12 # deallocate stack space
jr $ra # return to caller
Procedure Calls
Registers Usage Convention
Preserved Nonpreserved
Callee-Saved Caller-Saved
$s0 - $s7 $t0 - $t9
# $s0 = result
diffofsums:
addi $sp, $sp, -4 # make space on stack to store 1 register
sw $s0, 0($sp) # save $s0 on stack
# # no need to save $t0 or $t1...
add $t0, $a0, $a1 # $t0 = a + b
add $t1, $a2, $a3 # $t1 = c + d
sub $s0, $t0, $t1 # result = (a + b) - (c + d)
add $v0, $s0, $0 # put return value in $v0
lw $s0, 0($sp) # restore $s0 from stack
addi $sp, $sp, 4 # deallocate stack space
jr $ra # return to caller
Procedure Calls
proc1:
:
addi $sp, $sp, -4 # make space on stack
sw $ra, 0($sp) # save $ra on stack
jal proc2
:
lw $ra, 0($sp) # restore $s0 from stack
addi $sp, $sp, 4 # deallocate stack space
jr $ra # return to caller
Procedure Calls
factorial:
addi $sp, $sp, -8 # make room
sw $a0, 4($sp) # store $a0
sw $ra, 0($sp) # store $ra
addi $t0, $0, 2
slt $t0, $a0, $t0 # n == 1 ?
beq $t0, $0, else # no: go to else
addi $v0, $0, 1 # yes: return 1
addi $sp, $sp, 8 # restore $sp
jr $ra # return
else:
addi $a0, $a0, -1 # n = n - 1
jal factorial # recursive call
lw $ra, 0($sp) # restore $ra
lw $a0, 4($sp) # restore $a0
addi $sp, $sp, 8 # restore $sp
mul $v0, $a0, $v0 # n * factorial(n-1)
jr $ra # return
Procedure Calls
PC-Relative Addressing
:
0x00400024 beq $t0, $0, else
0x00400028 addi $v0, $0, 1
0x0040002C addi $sp, $sp, i
0x00400030 jr $ra
0x00400034 else: addi $a0, $a0, -1 # BTA (Branch Target Address)
0x00400038 jal factorial
:
• 26 bits are used to encode the target address and the two least significant bits,
should always be 0, because instructions are word aligned:
JTA 0000 0000 0100 0000 0000 0000 1010 0000 (0x004000A0)
26-bit addr 0000 0000 0100 0000 0000 0000 1010 0000 (0x0100028)
0 1 0 0 0 2 8
proc:
add $fp, $sp, $0 # $fp points to original top of stack
## do stuff with the array; mess with $a0 all you like