# This file can be used to write all the programs in PCSpim
# NAME:
# TA's NAME:
# DESCRIPTION:
## Example program in revised section 9.7 of Goodman and
## Miller's "A Programmer's View of Computer Architecture"
##
## This MAL program computes the greatest common divisor of
## two positive integers. The function that does the main
## calculation is recursive.
.data
# data items, i.e. all initialized and
# non-initialized items go in here
err_msg: .asciiz "\nbad integer entered\n"
.text
.globl main
main:
# your main subroutine code goes in here
jal intro
jal getint
beqz $v0, input_err
move $s0, $v1
jal getint
beqz $v0, input_err
move $a1, $v1
move $a0, $s0
jal gcd
move $a0, $v0
jal print_result
done
input_err: la $8, err_msg
puts ($8)
# the last line of main
done
# end of main
# any subroutines may be inserted here:...
## Intro
## A simple procedure to print a little introduction message.
## There are no parameters.
.data
msg1: .asciiz "This program computes the greatest common divisor of \n"
msg2: .asciiz "two user entered integers.\n\n"
.text
intro: la $8, msg1
puts ($8)
la $8, msg2
puts ($8)
jr $ra
## getint
## A function to get a single positive integer from the user.
## return values:
## $v0 -- flag indicating success of the function
## value is 1 if integer entered is ok.
## value is 0 if not ok.
## $v1 -- the integer entered
##
## register assignments:
## $8 -- user entered character
## $9 -- digit of integer
## $10 -- newline character (the constant)
## $11 -- the integer being entered
## $12 -- the constant 10, the base
## $13 -- temp
## $14 -- the constant 9
.data
prompt: .asciiz "Enter positive integer: "
.text
getint: li $10, 10 # $10 <- newline character
li $12, 10 # constant 10
li $11, 0
li $14, 9
la $13, prompt
puts ($13)
getchar: getc $8
beq $8, $10, getint_rtn
sub $9, $8, 48
bgt $9, $14, int_err
bltz $9, int_err
mul $11, $11, $12
add $11, $11, $9
b getchar
getint_rtn: li $v0, 1
move $v1, $11
jr $ra
int_err: li $v0, 0
jr $ra
## gcd
## A recursive function to calculate the greatest common divisor.
##
## gcd(m, n) = m if n = 0
## = gcd (n, m mod n) if n > 0
## return values:
## $v0 -- the greatest common divisor
## parameters:
## $a0 -- m
## $a1 -- n
##
.data
gcd_err_msg: .asciiz "error in calculating gcd -- quitting.\n"
.text
gcd: sub $sp, $sp, 12 # allocate activation record
sw $ra, 12($sp) # save return address
bgtz $a1, n_greater
bnez $a1, gcd_err
move $v0, $a0 # return m
b gcd_rtn
n_greater: sw $a0, 8($sp) # save current parameters
sw $a1, 4($sp)
rem $8, $a0, $a1
move $a0, $a1 # set up parameters for call
move $a1, $8
jal gcd # recursive call to gcd
lw $a0, 8($sp) # restore current parameters
lw $a1, 4($sp)
# return value already in $v0
gcd_rtn: lw $ra, 12($sp) # restore return address
add $sp, $sp, 12 # remove activation record
jr $ra # return
gcd_err: la $8, gcd_err_msg
puts ($8)
done
## print_result
## Procedure to print out the base ten integer passed to the procedure
## as a parameter
##
## return values:
## none
## parameters:
## $a0 -- the integer to be printed out
##
## register assignments:
## $8 -- address of output string
## $9 -- stack pointer before pushing characters onto stack
## $10 -- copy of integer to be printed
## $11 -- ASCII character code of digit to be printed as pushed
## $12 -- ASCII character code of digit to be printed as popped
## $13 -- newline character for nice output
.data
result_msg: .asciiz "The greatest common divisor is "
.text
print_result: move $10, $a0
la $8, result_msg
puts ($8)
move $9, $sp
bnez $10, push_loop
li $11, 0 # special case for printing 0
sw $11, 0($sp)
sub $sp, $sp, 4
b print_loop
push_loop: rem $11, $10, 10 # push characters onto stack
add $11, $11, 48
sw $11, 0($sp)
sub $sp, $sp, 4
div $10, $10, 10
bnez $10, push_loop
print_loop: add $sp, $sp, 4 # pop characters off stack
# and print
lw $12, 0($sp)
putc $12
bne $9, $sp, print_loop
li $13, 10 # print newline
putc $13
jr $ra
# END OF PROGRAM (leave this line here)
SQL Performance Dashboard Reports
Há 4 anos
0 comentários:
Enviar um comentário