This is an assignment. the idea is to prompt the user to:
- input the first positive integer
- input any one of the operations /,*,-,+
- input the second positive integer
Then, call do_math
which calls one of:
do_add
if operator is +, add the 2 inputs without using add or sub mips instruction and the return the result in a register. return an error condition if there is an overflow.
do_sub
if operator is -, subtract the second integer from the first without using sub or add mips instruction (you can call do_add twice) and return result in a register.
do_multiply
if operator is *, multiply the two inputs without using add, sub, mult and return result in two registers, one holds most significant 32 bits of product and the other holds the least 32 bits of the product. (which i did not do because i don't know how to extract them)
do_divide
if operator is /,divide without using add, sub, mult or div and returning the result in the form X OP Y = Z. where Z is replaced by Q remainder R. Q= QUOTIENT AND R= REMAINDER
Here are my concerns:
first how do i extract the 32 MSB and 32LSB of my product
when i run this code, the error messages are exception occurred at pc=0x004002bc can't expand stack segment by 12 bytes to 1048576 bytes. use -|stack #with > 1048576 unaligned address in instr/data fetch:0x7fffffff
i would really appreciate if someone told me what i am doing wrong and please i am still very new at everything. so be more explicit with your responds. thanks a lot
UPDATE: this is an update of yesterday's code. i think this is better because i do't have the error messages i had yesterday and also my system does not crash everytime i try to run this code. but unfortunately,i does not print the answer i want it to print. after successfully inputting the data, it just stop and nothing happens. can someone please tell me what i am doing wrong. thanks E
PS this code was kindly edited by someone else, with NOTe/BUG or NOTE/FIX. So please don't mind them if you comme across them.
this is my code:
.data
prompt: .asciiz "Please enter an integer\n"
message: .asciiz "Please enter an operator (+, - , * , / )\n:"
error1: .asciiz "invalid arithmetic operation "
err: .asciiz "Hmmmm!!! an overflow occured in one register"
newline: .asciiz "\n"
remainder: .asciiz "remainder"
sorry: .asciiz "sorry, division by zero is invalid"
equals: .asciiz "="
addition: .word 43
subtr: .word 45
multi: .word 42
divi: .word 47
input1: .word 1
input2: .word 1
.text
main:
li $v0,4 # system call code for printing a string
la $a0,prompt # string to print
syscall # telling the system to execute the action
li $v0,5 # system call for reading/displaying input
syscall # waits for input,puts input in $v0
sw $v0,0($s3)
li $v0,4
la $a0,message
syscall
li $v0,12 # code to get and print a char to the screen
syscall
move $a3,$v0 # putting the chracter in register $a3
li $v0,4
la $a0,newline
syscall
li $v0,4
la $a0,prompt # get the second integer
syscall
li $v0,5
syscall
la $s4,input2
sw $v0,0($s4)
blez $s3,main
blez $s4,main # we only want positive integers
jal do_math
do_math:
move $a1,$s3
move $a2,$s4
lw $t0,addition
beq $t0,$a3,adding
lw $t1,subtr
beq $t1,$a3,subtract
lw $t2,multi
beq $t2,$a3,multiply
lw $t3,divi
beq $t3,$a3,divide
li $v0,4
la $a0,error1 # print out the error message
syscall
li $v0,1
li $a3,5
syscall
j main #until we get the corrrect operator
adding:
jal do_add
j exit
subtract:
jal do_sub
j exit
multiply:
jal do_multiply
j exit
divide:
jal do_divide
j exit
exit:
li $v0,10
syscall
do_add:
addi $sp,$sp,-12
sw $ra,0($sp)
sw $a1,4($sp)
sw $a2,8($sp)
loop:
move $t8, $0
xor $a1,$a1,$a2 # adding the two numbers without a carry
and $t8,$a1,$a2 # determining the carry bits
sll $a2,$t8,1 # shift the carry bits one place left
bne $a2, $0, loop # perform this operation until there are no more carry bits
jal printanswer
move $a1, $v0
lw $ra,0($sp)
lw $a1,4($sp)
lw $a2,8($sp)
addi $sp,$sp,12
jr $ra
do_sub:
addi $sp,$sp,-12
sw $ra,0($sp)
sw $a1,4($sp)
sw $a2,8($sp)
nor $a2,$a2,$a2 # flip the bits but number decreases by one so...
xori $a1,$zero,1 # find the 2s complement
jal do_add
move $a2,$v0
lw $a1, 4($sp)
jal do_add # to add the user inputs
move $a1,$v0
jal printanswer
lw $ra,0($sp)
lw $a1,4($sp)
lw $a2,8($sp)
addi $sp,$sp,12
jr $ra
do_multiply:
beq $a1, $0, done
beq $a2, $0, done
addi $sp,$sp,-12
sw $ra,0($sp)
sw $a1,4($sp)
sw $a2,8($sp)
sll $a1, $a1, 5 #extend the multiplicant bits to 32 bits
sll $a2, $a2, 6 #extend the multiplier bits to 64 and it now becomes the product(in the book)
mult_loop:
move $s0, $0
xor $s0,$s0,1
blt $s0, 5,loop1
j printmult
loop1:
andi $a2,$a2,1 # get the least significant bit and put it in the $a2
beqz $a2,then
jal do_add
move $a2, $v0
srl $a2, $a2, 1
j mult_loop
printmult:
jal printansmult
then:
srl $a2, $a2, 1
j mult_loop
lw $ra,0($sp)
lw $a1,4($sp)
lw $a2,8($sp)
addi $sp,$sp,12
jr $ra
done:
jr $ra
do_divide:
sll $a1,$a1,4 # this is going to be our remainder
sll $a2,$a2,4 # this is the divisor
sll $a3,$a3,3 # this is the quotient
addi $sp,$sp,-12
sw $ra,0($sp)
sw $a1,4($sp)
sw $a2,8($sp)
sw $a3,12($sp)
counter:
move $t6,$0
xor $t6,$t6,1
beq $t6,17,exit
loopdiv:
jal do_sub
move $a1,$v0 # subtract divisor from remainder and put result in remainder
# getting the msb significant bit
andi $t5,$a1,32768
blt $t5,$0,quotientupdate
sll $a3,$a3,1 # shift quotient left
ori $a3,$a3,1 # add one to the least significant bit of quotient
srl $a2,$a2,1
j counter
move $t5,$a3
move $t6,$a1
jal printdivans
lw $ra,0($sp)
lw $a1,4($sp)
lw $a2,8($sp)
lw $a3,12($sp)
addi $sp,$sp,16
jr $ra
quotientupdate:
jal do_add
move $a1,$v0
sll $a3,$a3,1 # shift quotient left
ori $a3,$a3,0 # add zero to the least significant bit of quotient
srl $a2,$a2,1
j counter
# NOTE/BUG: this is dead/never reached code
move $t5,$a3
move $t6,$a1
jal printdivans
lw $ra,0($sp)
lw $a1,4($sp)
lw $a2,8($sp)
lw $a3,12($sp)
addi $sp,$sp,12
jr $ra
printanswer:
lw $a1, 4($sp)
li $v0,1
syscall
jr $ra
printansmult:
la $a1, 4($sp)
li $v0,1
syscall
jr $ra
printdivans:
lw $a0,input1
li $v0,1
syscall
la $a0,divi
li $v0,4
syscall
li $v0,1
la $a0,input2
syscall
li $v0,4
la $a0,equals
syscall
li $v0,1
la $a0,4($sp)
syscall
li $v0,4
la $a0,remainder
syscall
li $v0,1
la $a0,8($sp)
syscall