rss
twitter
facebook

Home

This program does simple vector addition

# NAME:
# TA's NAME:
# DESCRIPTION:

##     Example Program in section 9.7 (p 243) of "A Programmer's
##    View of Computer Architecture" of Goodman and Miller
##
##    This program does simple vector addition

    .data

# data items, i.e. all initialized and
# non-initialized items go in here

prompt1:    .asciiz "Vector addition program\n"
prompt2:    .asciiz "Please enter a vector\n"
linefeed:    .byte '\n'
err_msg:    .asciiz "Error encountered - quitting\n"

    .text
    .globl main

main:   
# your main subroutine code goes in here

    la $8, prompt1
    puts ($8)
    la $8, prompt2
    puts ($8)
    jal get_vector
    beq $2, $0, error1

# copy parameters out of registers
    move $16, $4        # $16 is x1
    move $17, $5        # $17 is y1
    move $18, $6        # $18 is z1

    la $8, prompt2
    puts ($8)
    jal get_vector
    beq $2, $0, error1

# copy parameters out of registers
    move $19, $4
    move $20, $5
    move $21, $6

# push parameters on stack for addition procedure

    add $sp, $sp, -24
    sw $16, 24($sp)
    sw $17, 20($sp)
    sw $18, 16($sp)
    sw $19, 12($sp)
    sw $20, 8($sp)
    sw $21, 4($sp)

    jal vector_add
    add $sp, $sp, 24    # pop parameters and discard

# the results x3, y3, z3 are already in $4, $5, and $6
# so don't move them

    jal print_result

# the last line of main
    done

# end of main
# any subroutines may be inserted here:...

error1:    la $8, err_msg
    puts ($8)
    done

# get_vector -- a procedure to get an x, y, and z for
#         a vector
# return values: $2 -- error flag, 0 if there is an error
#         $4 -- the x value
#         $5 -- the y value
#         $6 -- the z value

    .data
getx:    .asciiz "Enter x: "
gety:    .asciiz "Enter y: "
getz:    .asciiz "Enter z: "

    .text
get_vector:
    sw $31, 0($sp)    #  pushgm (Release 2.03) is a macro of original
    add $sp, $sp, -4    #  code in textbook

    la $8, getx    #  get x
    puts ($8)
    jal get_integer
    beq $2, $0, return1
    move $22, $3

    la $8, gety    #  get y
    puts ($8)
    jal get_integer
    beq $2, $0, return1
    move $23, $3

    la $8, getz    #  get z
    puts ($8)
    jal get_integer
    beq $2, $0, return1
    move $24, $3

return1:
    move $4, $22
    move $5, $23
    move $6, $24

    add $sp, $sp, 4
    lw $31, 0($sp)
    jr $31

# get_integer -- a procedure to form an integer from
#    a single line of user input
# return values:
#    $2 -- error flag, 0 if there is an error
#    $3 -- the integer value

    .data
    bias = 48

    .text
get_integer:
    sw $31, 0($sp)    # save return address
    add $sp, $sp, -4
    li $15, 1    # initialize variables
    li $3, 0
    lbu $11, linefeed
            # $11 -- the <CR> character

    li $9, bias    # $9 -- '0' ASCII character
            # code
            # NOTE: Not the same as original
            # using 'lw'

    li $13, '0'
    li $14, '9'
    getc $8        # $8 -- the user input character

get_digit:
    beq$8, $11, return2
            # integer is complete
            # when <CR> read
    blt $8, $13, bad_input
    bgt $8, $14, bad_input
    sub $10, $8, $9
    mul $3, $3, 10
    add $3, $3, $10
    getc $8
    b get_digit

bad_input:
    li $15, 0

return2:
    move $2, $15
    add $sp, $sp, 4    # restore return address
    lw $31, 0($sp)
    jr $31

# vector_add -- a procedure to add 2 vectors together
# return values:
#    $2 -- error flag, 0 if there is an error
#    $4 -- the x component
#    $5 -- the y component
#    $6 -- the z component
# parameters: on stack, x1, y1, z1, x2, y2, z2

vector_add:
    sw $31, 0($sp)    # save return address
    add $sp, $sp, -4

    lw $8, 28($sp)    # pop x components and add
    lw $9, 16($sp)
    add $4, $8, $9

    lw $8, 24($sp)    # pop y components and add
    lw $9, 12($sp)
    add $5, $8, $9

    lw $8, 20($sp)    # pop x components and add
    lw $9, 8($sp)
    add $6, $8, $9

return3:
    add $sp, $sp, 4    # restore return address
    lw $31, 0($sp)
    jr $31

# print_result -- a procedure to print out the 3 values
#    computed
# return values: none
# parameters:
#    $4 -- the x component to be printed
#    $5 -- the y component to be printed
#    $6 -- the z component to be printed

    .data
msg:    .asciiz "The result of the vector addition: \n"
x_msg:    .asciiz "x = "
y_msg:    .asciiz "y = "
z_msg:    .asciiz "z = "

    .text
print_result:
    sw $31, 0($sp)        # save return address
    add $sp, $sp, -4

    add $sp, $sp, -12    # save parameters, since
    sw $4, 12($sp)        # other procedures like
    sw $5, 8($sp)        # 'puts' also use $4 - $7
    sw $6, 4($sp)

    la $8, msg
    puts ($8)

    la $8, x_msg
    puts ($8)
    lw $4, 12($sp)        # x is on the stack
    jal print_int
    la $9, linefeed
    lbu $9, 0($9)
    putc $9

    la $8, y_msg
    puts ($8)
    lw $4, 8($sp)        # y is on the stack
    jal print_int
    la $9, linefeed
    lbu $9, 0($9)
    putc $9

    la $8, z_msg
    puts ($8)
    lw $4, 4($sp)        # z is on the stack
    jal print_int
    la $9, linefeed
    lbu $9, 0($9)
    putc $9

    lw $4, 12($sp)    # restore parameters
    lw $5, 8($sp)
    lw $6, 4($sp)
    add $sp, $sp, 12

return4:
    add $sp, $sp, 4    # restore return address
    lw $31, 0($sp)

    jr $31

# print_int -- a procedure to print out an integer
# return values: none
# parameters: $4 -- the integer to be printed

print_int:
    sw $31, 0($sp)    # save return address
    add $sp, $sp, -4

    li $10, 0    # $10 -- count of
            # number of digits

    move $12, $4
    sw $4, 0($sp)
    add $sp, $sp, -4

# repeat loop to peel off digits from the least
# significant end of the value
repeat:
    rem $9, $12, 10
    div $12, $12, 19
    add $9, $9, 48    # add back in the bias
    sw $9, 0($sp)    # push ASCII char. on stack
    add $sp, $sp, -4
    add $10, $10, 1
    bne $12, $0, repeat

# repeat loop to print out the characters stored on stack
print_em:
    add $sp, $sp, 4
    lw $11, 0($sp)
    putc $11
    sub $10, $10, 1
    bne $10, $0, print_em

    add $sp, $sp, 4
    lw $4, 0($sp)
return5:
    add $sp, $sp, 4
    lw $31, 0($sp)
    jr $31

# END OF PROGRAM (leave this line here)

0 comentários:

 
Powered by Blogger