Download presentation
Presentation is loading. Please wait.
1
CSCI206 - Computer Organization & Programming
Call Conventions, Factorial zyBook: 8.2
2
Factorial int fact (int n) { if (n < 1) return (1); else return (n * fact(n-1)); } To implement factorial, we need to first explain multiply (and divide) in MIPS.
3
How mult and div work (green sheet)
Both are R-type instructions with only two arguments Results are stored in the hi/lo registers internal to the ALU mult rs, rt {hi, lo} = R[rs] * R[rt] # 64 bit result! div rs, rt lo = R[rs] / R[rt], hi = R[rs] % R[rt]
4
mflo, mfhi ALU access instructions, mflo, mfhi
move from lo move from hi Transfer data from the hi/lo registers to an architectural register for general use
5
example mult mult $a0, $a1 # hi,lo = a0 * a1
mflo $a # lower 32 bits to a0 mfhi $a1 # upper 32 bits to a1 bgtz $a1, overflow # 32 bit overflow
6
example div div $a0, $a1 mflo $a0 # quotient [int (a0/a1)]
mfhi $a1 # remainder [a0 % a1]
7
pseudo instructions mul rd, rs, rt ==> mult rs, rt ; mflo rd
div rd, rs, rt ==> div rs, rt; mflo rd Stop, do activity 14a.
8
Factorial (1) Stack $ra One call to fact $a0 $sp
fact: # PC == 0x c addi $sp, $sp, -8 # create space for 2 items sw $ra, 4($sp) # save return address sw $a0, 0($sp) # save argument slti $t0, $a0, 1 # $t0 = 1 if n < 1 beq $t0, $zero, Else # if n>=1, go to Else addi $v0, $zero, 1 # return 1 addi $sp, $sp, 8 # pop 2 words off the stack jr $ra # return to caller Else: # PC == 0x c addi $a0, $a0, -1 # n>=1: n = n-1 jal fact # fact(n=n-1) PC == 0x lw $a0, 0($sp) # restore save argument n lw $ra, 4($sp) # restore return address mul $v0, $a0, $v0 # $v0 = n * fact(n-1) int fact (int n) { if (n < 1) return (1); else return (n * fact(n-1)); }
9
Factorial (2) local / automatic variable, located on the stack
1 2 3 4 5 6 7 8 9 10 11 int fact (int n) { int result; if (n < 1) result = 1; else result = n * fact(n-1); return result; } local / automatic variable, located on the stack single return, value from stack
10
Factorial (2) fact: addi $sp, $sp, -12 # create space for 3 items
sw $ra, 8($sp) # save return address sw $a0, 4($sp) # save argument slti $t0, $a0, 1 # $t0 = 1 if n < 1 beq $t0, $zero, Else # if n>=1, go to Else li $t0, # setup for base-case sw $t0, 0($sp) # store 1 in result j fact_return Else: addi $a0, $a0, -1 # n>=1: n = n-1 jal fact # fact(n=n-1) PC = 0x0x01FC lw $a0, 4($sp) # restore saved argument n mul $t0, $a0, $v0 # $v0 = n * fact(n-1) sw $t0, 0($sp) # store result on stack #fall through to return fact_return: lw $ra, 8($sp) # restore return address lw $v0, 0($sp) # get result addi $sp, $sp, 12 # pop 3 words off the stack jr $ra # return to caller Factorial (2) 1 2 3 4 5 6 7 8 9 10 11 int fact (int n) { int result; if (n < 1) result = 1; else result = n * fact(n-1); return result; }
11
fact: addi $sp, $sp, -8 # create space for 3 items sw $ra, 4($sp) # save return address sw $a0, 0($sp) # save argument slti $t0, $a0, 1 # $t0 = 1 if n < 1 beq $t0, $zero, Else # if n>=1, go to Else li $v0, # setup for base-case j fact_return Else: addi $a0, $a0, -1 # n>=1: n = n-1 jal fact # fact(n=n-1) lw $a0, 0($sp) # restore saved argument n mul $v0, $a0, $v0 # $v0 = n * fact(n-1) #fall through to return fact_return: lw $ra, 4($sp) # restore return address addi $sp, $sp, 8 # pop 2 words off the stack jr $ra # return to caller Factorial (2b) 1 2 3 4 5 6 7 8 9 10 11 int fact (int n) { int result; if (n < 1) result = 1; else result = n * fact(n-1); return result; } Because result is assigned after all other function calls, we can use a register to hold this local variable. This is an optimization!
12
Factorial (3) Delayed stack setup is ok!
blt $a0, 13, check_facts # check n li $v0, 0 jr $ra # if n > 12, return immediately check_facts: sll $t0, $a0, 2 # byte offset of n lw $v0, facts($t0)# load facts[n] bgtz $v0, fact_return # branch if lookup worked compute_fact: slti $t0, $a0, 1 # $t0 = 1 if n < 1 beq $t0, $zero, L1 # if n>=1, go to L1 li $v0, # setup for base-case j fact_return L1: addi $sp, $sp, -8 # create space for 2 items sw $ra, 4($sp) # save return address sw $a0, 0($sp) # save argument addi $a0, $a0, -1 # n>=1: n = n-1 jal fact # fact(n=n-1) PC = 0x0x01FC lw $a0, 0($sp) # restore saved argument n lw $ra, 4($sp) # restore return address mul $v0, $a0, $v0 # $v0 = n * fact(n-1) addi $sp, $sp, 8 # pop 2 words off the stack #fall through to return fact_return: sll $t0, $a0, 2 # byte offset sw $v0, facts($t0)# save result in facts[n] jr $ra # return to caller 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 int facts[12] = {0}; int fact (int n) { if (n > 12){ return 0; } if (facts[n] == 0){ if (n < 1){ facts[n] = 1; } else { facts[n] = n * fact(n-1); return facts[n]; Delayed stack setup is ok! Use look-up table for previously computed results!
Similar presentations
© 2024 SlidePlayer.com. Inc.
All rights reserved.