# # program to define and test division function with # parameter pointers: # # return 1 for okay, 0 for division by zero # int divide(int a, int b, int * quotient, int * remainder) { # if (b == 0) { # return 0; # } else { # *quotient = a / b # *remainder = a % b # return 1; # } # } # .text .globl main main: # # opening linkage (save return address) # addi $sp, $sp, -4 sw $ra, 0($sp) # # prompt # la $a0, prompt li $v0, 4 # "print string" syscall syscall # # get input # # $s0, $s1 will hold inputs a, b # li $v0, 5 # "read int" syscall syscall addi $s0, $v0, 0 # save result in $s0 (a) li $v0, 5 # "read int" syscall syscall addi $s1, $v0, 0 # save result in $s1 (b) # # call divide function, putting result in variables q, r # addi $a0, $s0, 0 # a addi $a1, $s1, 0 # b la $a2, q la $a3, r jal divide # # print results # # C-like pseudocode: # if (return value == 0) { # printf("Division not allowed\n"); # } else { # printf("(a, b, q, r) = (%d, %d, %d, %d)\n", a, b, q, r); # } bne $v0, $zero, notzero # error message if return value 0 la $a0, errmsg li $v0, 4 # "print string" syscall syscall j end # results if return value is not 0 notzero: la $a0, answer_txt1 li $v0, 4 # "print string" syscall syscall addi $a0, $s0, 0 # a li $v0, 1 # "print int" syscall syscall la $a0, sep # ", " li $v0, 4 # "print string" syscall syscall addi $a0, $s1, 0 # b li $v0, 1 # "print int" syscall syscall la $a0, sep # ", " li $v0, 4 # "print string" syscall syscall lw $a0, q li $v0, 1 # "print int" syscall syscall la $a0, sep # ", " li $v0, 4 # "print string" syscall syscall lw $a0, r li $v0, 1 # "print int" syscall syscall la $a0, answer_txt2 li $v0, 4 # "print string" syscall syscall end: # # closing linkage (get return address and restore stack pointer) # lw $ra, 0($sp) addi $sp, $sp, 4 jr $ra .end main # # divide function: # divide: # # opening linkage (save return address and registers) # addi $sp, $sp, -4 sw $ra, 0($sp) addi $sp, $sp, -32 sw $s0, 0($sp) sw $s1, 4($sp) sw $s2, 8($sp) sw $s3, 12($sp) sw $s4, 16($sp) sw $s5, 20($sp) sw $s6, 24($sp) sw $s7, 28($sp) # # do computation and set return value # # in C: # int divide(int a, int b, int * quotient, int * remainder) { # if (b != 0) goto notzero; # return 1; # goto end; # notzero: # *quotient = a / b; # *remainder = a % b; # return 0; # end: # } bne $a1, $zero, divide_notzero li $v0, 0 # return value j divide_end divide_notzero: div $a0, $s1 # divide a by b mflo $t0 # a / b sw $t0, 0($a2) # *q = a / b mfhi $t0 # a % b sw $t0, 0($a3) # *r = a / b li $v0, 1 # return value divide_end: # # closing linkage # lw $s7, 28($sp) lw $s6, 24($sp) lw $s5, 20($sp) lw $s4, 16($sp) lw $s3, 12($sp) lw $s2, 8($sp) lw $s1, 4($sp) lw $s0, 0($sp) addi $sp, $sp, 32 lw $ra, 0($sp) addi $sp, $sp, 4 # return to caller jr $ra .end factorial # # area for variables and constants # .data # variables for storing function results q: .word 0 r: .word 0 # text strings for prompt, output prompt: .asciiz "Enter two integers:\n" errmsg: .asciiz "Division by zero not allowed\n" answer_txt1: .asciiz "(a, b, a / b, a % b) = (" sep: .asciiz ", " answer_txt2: .asciiz ")\n"