This is the C code that i have been converted so far. it gives me some error that i have been included in the following code. i don't understand which part is wrong in this c to mips conversion?
char ch[10];
int i;
for (i = 0; i != 10; i++)
ch[i] = ch[i] – 32
.data
.text
li $v0 4
syscall
#$s1 = i, $s0 base address of ch
addi $s1, $0, 0 #i =0
addi $t0, $0, 10 #t0 = 10
loop: beq $t0, $s1, end
add $t1, $s1, $s0
lw $t2, 0($t1)
addi $t2, $t2, -32
sw $t2, 0($t1)
addi $s1, $s1, 1
j loop
end:
My output:
Runtime exception at 0x00400018: address out of range 0x00000000
From the C code you are converting a char type array and in MIPS you should use lb instead of lw.
In order to print out you need a main: label and also you should declare an array like .byte or .space
You should usesyscall 11 to print a character or syscall 4 to print
string.
I have added some of these mentioned above to your code hope it helps.
.data
#ch: .byte 'a','b','c','d','e'
ch: .space 10
.text
main:
li $v0, 8 #read character
li $a1, 10 #load the space
la $a0, ch
syscall
li $v0,11 #print character
syscall
li $v0,10 # exit program
syscall
addi $s1, $0, 0 #i = 0
addi $t0, $0, 10 # $t0 = 10
loop: beq $t0, $s1, end
add $t1, $s1, $s0
lb $t2, ch($t1)
addi $t2, $t2, -32
sb $t2, ch($t1)
addi $s1, $s1, 1
j loop
end:
Related
I am trying an array to save i * j values and print the values from array.
I have two loops loop1, loop2, where loop1 takes i and loop2 takes on j.
I am trying to save the i * j in a myarray which is space datatype.
I am getting exception Memory address out of bounds and unable to find whats the error.
.data
myarray: .space 10000
n: .word 1
space_line: .asciiz " "
new_line: .asciiz "\n"
.text
.globl main
main:
lw $a0, n
la $a1, myarray
li $a2, -1 #row
li $t0, 0
li $t2, 0
loop1:
addi $a2, $a2,1
bge $a2, $a0, print_loop
li $a3, 0 #column
j loop2
loop2:
bge $a3, $a0, loop1
#multiply a2 and a3
mul $t1, $a2, $a3
sw $t1, 0($a1)
addu $a1, $a1,4
addi $a3, $a3,1
j loop2
print_loop:
mul $t3, $a0, $a0
bge $t0, $t3, exit
li $v0, 4
lw $a0, myarray($t2)
syscall
li $v0, 4
lw $a0, space_line
syscall
rem $t4, $t3, $a0
beqz $t4, newline
addu $t2, $t2, 4
addi $t0, $t0, 1
j print_loop
newline:
li $v0, 4
lw $a0, myarray($t2)
syscall
exit:
# Done, terminate program.
li $v0, 10
syscall # all done!
.end main
For n =4,i am expecting the output in console as
0 0 0 0
0 1 2 3
0 2 4 6
0 4 8 12
You can find this problem by single stepping in the debugger. Start with the smallest possible input, like n=1 as you're showing. After each instruction, verify that it did what you want, and that it didn't do anything else except what you wanted.
Here's a hint: Pay attention to the difference between la and lw. Also, If you want to put syscalls in the middle of your code or loops, then avoid the $a0 and $v0 registers for your own variables — just makes things easier/better.
This is a follow up of my previous question which I edited:
How to remove a comma from string input
I managed to fix the infinite loop, and found a way to increment through the string. My code now can, iterate through a string(eg. 123,456) find the address of the "," and stores in $t4.
But what I can't figure out is how to shift all the numbers towards the left to remove the "," from the string(should look like this in the memory 123,456 -> 123456)
I'm using native MIPS instructions. If you could help me out like that, I would really appreciate it.
.globl main
.globl main2
.globl main3
.globl firstNumCountChr
.globl firstNumIncrem
.globl secondNumCountChr
.globl secondNumIncrem
.globl thirdNumCountChr
.globl thirdNumInCrem
.data
prompt1: .asciiz "Enter first number:"
prompt2: .asciiz "Enter second number:"
prompt3: .asciiz "Enter third number:"
.text
# 0x10000000 will store first number
# 0x10000008 will store second number
# 0x10000010 will store third number
main:
#display prompt1
addi $v0, $0, 4
lui $a0, 0x1000
syscall
#Input first number
lui $a0, 0x1000
ori $a0, 0x0000 #reads number into memory(0x10000000)
addi $a1, $0, 8 #7 characters
addi $v0, $0, 8
syscall
#removing comma of first number
add $t1, $0, $0 #$t1 is the counter set to 0
add $t3, $0, 0x2c # 0x2c is acsii of "," in hex
firstNumCountChr:
lb $t2, 0($a0) #load first byte from address in $a0
beq $t2, $0, firstNumRemoveComma #if $t2 == 0 go to firstNumRemoveComma
or $0, $0, $0 #NOP
bne $t2, $t3, firstNumIncrem #branch if symbol doesn't equal ","
or $0, $0, $0
add $t4, $a0, $0 #$t4 will save position of ","
firstNumIncrem:
addi $a0, $a0, 1 #increment address
addi $t1, $t1, 1 #increment counter
j firstNumCountChr #loop
firstNumRemoveComma:
beq $t4, $0, main2 #branch if $t4 == 0 (no comma) to main2
or $0, $0, $0 #NOP
main2:
#display prompt2
addi $v0, $0, 4
lui $a0, 0x1000
addi $a0, $a0, 20
syscall
#inputing second number
lui $a0, 0x1000
ori $a0, 0x0008 #reads number into memory(0x10000008)
addi $a1,$0, 8 #7 characters
addi $v0, $0, 8
syscall
#removing comma of second number
addi $t1, 0 # $t1 is the counter set to 0
add $t3, 0x2c # 0x2c is acsii of "," in hex
secondNumCountChr:
lb $t2, 0($a0) # load first byte from address in $a0
beq $t2, $0, end # if $t2 == 0 go to end
or $0, $0, $0 # NOP
bne $t2, $t3, secondNumIncrem # branch if symbol doesn't equal ","
or $0, $0, $0 # NOP
add $t4, $a0, $0 # $t4 will save position of ","
secondNumIncrem:
addi $a0, $a0, 1 #increment address
addi $t1, $t1, 1 #increment counter
j secondNumCountChr #loop
main3:
#display prompt3
addi $v0, $0, 4
lui $a0, 0x1000
addi $a0, $a0, 41
syscall
#inputting third number
lui $a0, 0x1000
ori $a0, 0x0010 #reads number into memory(0x10000010)
addi $a1, $0, 8 #7 characters
addi $v0,$0, 8
syscall
#removing comma of third number
addi $t1, 0 #$t1 is the counter set to 0
add $t3, 0x2c # 0x2c is acsii of "," in hex
thirdNumCountChr:
lb $t2, 0($a0) #load first byte from address in $a0
beq $t2, $0, end # if $t2 == 0 go to end
or $0, $0, $0
bne $t2, $t3, thirdNumInCrem # branch if symbol doesn't equal ","
or $0, $0, $0
add $t4, $a0, $0 # $t4 will save position of ","
thirdNumInCrem:
addi $a0, $a0, 1 #increment address
addi $t1, $t1, 1 #increment counter
j thirdNumCountChr #loop
end:
add $0, $0, $0
I am trying to add numbers that are in base 5.
Im supposed to prompt the user for 2 separate base 5 number in the form XXXXXX.XXXXX, and then add them.
My current problem is that I am getting an error when I am loading the last digit into a register, so I can start the calculation.
please help! Thanks
.data
str: .space 13 # XXXXXX.XXXXX hold 12 chars + 0x00
str2: .space 13
sum: .space 14
printstr: .space 13
printstr2: .space 13
printsum: .space 14
message1: .asciiz "Enter a base 5 number A: "
message2: .asciiz "Enter a base 5 number B: "
message3: .asciiz "Sum of A and B: "
newline: .asciiz "\n"
.text
main:
#get number A
li $v0, 4
la $a0, message1
syscall
li $v0, 8
li $a1, 13
la $a0, str
syscall
li $v0, 4
la $a0, newline
syscall
#get number B
li $v0, 4
la $a0, message2
syscall
li $v0, 8
li $a1, 13
la $a0, str2
syscall
li $v0, 4
la $a0, newline
syscall
#pointer to input string A
la $s1, str
addi $s1, $s1, 12
#pointer to input string A
la $s2, str2
addi $s2, $s2, 12
#pointer to sum
la $s3, sum
addi $s3, $s3, 13
#other variables
li $t0, 0 # inital carry is 0
li $t1, 1 # counter for looping through string
li $t2, 5 # base 5
loop:
lb $t3, ($s1) ############################# PROBLEM HERE######
lb $t4, ($s2)
beq $t3, '.', next
beq $t4, '.', next
subi $t3, $t3, 0x30
subi $t4, $t4, 0x30
add $t5, $t3, $t4
add $t5, $t5, $t0
div $t5, $t2
mflo $t0
mfhi $t5
addi $t5, $t5, 0x30
sb $t5, ($s3)
subi $s1, $s1, 1
subi $s2, $s2, 1
subi $s3, $s3, 1
addi $t1, $t1, 1
ble $t1, 13, loop
addi $t0, $t0, 0x30
sb $t0, ($s3)
next:
subi $s1, $s1, 1
subi $s2, $s2, 1
#subi $s3, $s3, 1
addi $t1, $t1, 1
j loop
PRINT: #print the sum
exit:
li $v0, 10
syscall
You set up $s1 to point past str and decrement it backwards. Your loop: termination is the ble $t1,13,loop. When that completes, $s1 is pointing to the start of the .data section (i.e. 0x10010000).
But, then, you "fall through" to next: [probably wrong] and decrement $s1 so it has the value 0x1000ffff. Then, you do j loop so the fetch is now coming from an address one byte below the start of the .data segment (i.e. memory that does not exist)
That's the source of the crash. You probably need a jump inst after the ble to continue on to some other code.
But, also, when you do beq $t3,'.',next you go to next: and decrement both pointers. Unless you restrict your input there is no guarantee that both $s1 and $s2 both point to '.' at the same time, so you only want to decrement one of them. (e.g. suppose you had str: 12.3 and str2: 123.41)
So, you may need some code to align the two numbers with respect to their decimal points beforehand.
I have a trouble. I tried to make a binary search algorithm using recursion in mips assembly, but I have some errors that I don't understand how to solve them.
I have an array of 10 integers and I assume that the array is sorted.
this is my code, I appreciate any help and thanks in advance..
.data
arr: .word 40
arrMsg: .asciiz "Enter the array : \n"
posMsg: .asciiz "This value exist in the array and its position is "
pos: .word 0
newline: .asciiz "\n"
valMsg: .asciiz "Enter the value you search for : \n"
val: .word 0
notfound:.asciiz "the value doesn't exist in the array !! \n"
.text
main:
# print the array message
li $v0, 4
la $a0, arrMsg
syscall
# read the array from the user
# put $s0 = i
add $s0, $zero, $zero # i = 0
for:
beq $s0, 40, end
li $v0, 5
syscall
sw $v0, arr($s0) # input arr[i]
addi $s0, $s0, 4 # i = i + 4
j for
end:
# print value message
li $v0, 4
la $a0, valMsg
syscall
# read the value from the user
li $v0, 5
syscall
# store the value in the val variable
sw $v0, val
################################################
## put $s0 = start , $s1 = middle , $s2 = end ##
################################################
li $s0, 0
li $s2, 9
jal BinarySearch
li $v0, 10
syscall
############################################################################################################
BinarySearch:
# middle = (start + end ) / 2
add $t0, $s0, $s2 # $t0 = start + end
sra $s1, $t0, 1 # $s1 = $t0 / 2
# save $ra in the stack
addi $sp, $sp, -4
sw $ra, 0($sp)
# base case
ble $s2, $s0, returnNegative1 # if (end <= start)
lw $t1, arr($s1) # $t1 = arr[middle]
lw $t2, val # $t2 = val
beq $t1, $t2, returnMiddle # if (arr[middle] == val)
blt $t2, $t1, returnFirstPart # if (val < arr[middle])
bgt $t2, $t1, returnLastPart # if (val > arr[middle])
returnNegative1:
li $v0, -1
j Exit
returnMiddle:
move $v0, $s1 # return middle
j Exit
returnFirstPart:
move $t3, $s1 # temp = middle
addi $t3, $t3, -1 # temp --
move $s2, $t3 # end = temp
jal BinarySearch
j Exit
returnLastPart:
move $t3, $s1 # temp = middle
addi $t3, $t3, 1 # temp++
move $s0, $t3 # start = temp
jal BinarySearch
j Exit
Exit:
lw $ra, 0($sp)
addi $sp, $sp, 4`
jr $ra
lw $t1, arr($s1) # $t1 = arr[middle]
this is the problem as it is not really the right index as integer takes 4 bytes
so the middle you get from
add $t0, $s0, $s2 # $t0 = start + end
sra $s1, $t0, 1 # $s1 = $t0 / 2
is just the logical address not the real one you will need to multiply it with 4
mul $s4, $s1,4
and then use $s4 as an address
lw $t1, arr($s4) # $t1 = arr[middle]
also there is a mistake with the stopping condition it should be
if (end < start) not (<=)
and sorry for my English
So i have to write a bubblesort programm in mips using QtSpim for a class but i get an Exception 4 [Adress error in inst/data fetch]. I have searched in other topics and use the .align 2 directive before defining an array for 5 integers but it still isn't getting fixed.
Here's the code:
.text
.globl main
main:
la $t1, array #sets the base adress of the array to t1
la $a0, in_prompt
li $v0, 4
syscall
li $t2, 0 #init to 1
read_loop:
beq $t2, 5, read_key #break if t2 = 5
la $a0, num_prompt
li $v0, 4
syscall #"Give number"
#move $a0, $t2
#li $v0, 1
#syscall #current number to be read
li $v0, 5 #read int. 5 times
syscall
sw $v0, ($t1) #move input from v0 to the array
addi $t1, $t1, 4 #move t1 to the next position in the array
addi $t2, $t2, 1 #increment counter (t2) by 1
j read_loop
read_key:
la $a0, search_q
li $v0, 4
syscall #print query prompt
li $v0, 5
syscall
move $t3, $v0 #number we're looking for (KEY)
move $a0, $t1 #array to pass as arguement
jal bubblesort
move $a0, $v0 #move into a0 the sorted array
move $a1, $t3 #move the KEY into a1 as arguement
jal binarysearch
move $t1, $a0 #move into t1 the array
move $t0, $a1 #move into t0 the KEY
move $t3, $v0 #move into t3 the result of binarySearch
beq $t3, -1, not_found #if key was not found
move $a0, $t0
li $v0, 1
syscall
la $a0, found_pr
li $v0, 4
syscall
j print_array
not_found:
move $a0, $t0
li $v0, 1
syscall
la $a0, not_found_pr
li $v0, 4
syscall
j print_array
print_array:
li $t2, 1 #init to 1
print_loop:
beq $t2, 5, EXIT
lw $a0, ($t1)
li $v0, 1
syscall
addi $t1, $t1, 4
addi $t2, $t2, 1
j print_loop
EXIT:
li $v0, 10
syscall
##############binarysearch#################
binarysearch:
addi $sp, $sp, -24 #reserve space for 6 elements
sw $a0, 0($sp) #push a0 (array)into stack
sw $a1, 4($sp) #push a1(KEY) into stack
sw $s0, 8($sp) #push s0
sw $s1, 12($sp) #push s1
sw $s2, 16($sp) #push s2
sw $ra, 20($sp) #push ra
sw $s3, 24($sp) #push s3
li $s0, 0 #low = 0
li $s1, 4 #high = 4
while:
bgt $s0, $s1, exit_search #if low > high branch
move $a1, $s0 #move into a1 low
move $a2, $s1 #move into a2 high
jal calc_middle #jump to calc_middle
move $s2, $v0 #move into s2 the return value of calc_middle
lw $a0, 0($sp) #restore into a0 the 1st stack el(array)
lw $a1, 4($sp) #restore into a1 the 2nd stack el(KEY)
add $a0, $a0, $s2 #move the array to middle
lw $s3, ($a0) #load into s3 the a[middle]
beq $a1, $s3, exit_search_found #break if KEY == a[middle]
blt $a1, $s3, less_t_middle #if the key is less than the middle element
addi $s0, $s2, 1 #if the key is greater than the middle element set new low
j while
less_t_middle:
addi $s1, $s2, -1 #new high
j while
exit_search_found:
move $v0, $s2 #return found
lw $s0, 8($sp)
lw $s1, 12($sp)
lw $s2, 16($sp)
lw $ra, 20($sp)
addi $sp, $sp, 24
jr $ra
exit_search:
li $v0, -1 #return -1
lw $s0, 8($sp)
lw $s1, 12($sp)
lw $s2, 16($sp)
lw $ra, 20($sp)
addi $sp, $sp, 24
jr $ra
##############calc_middle##################
calc_middle:
add $a1, $a1, $a2
sra $a1, $a1, 1
move $v0, $a1
jr $ra
##############bubblesort###################
bubblesort:
addi $sp, $sp, -12
sw $s0, 0($sp)
sw $s1, 4($sp)
sw $s2, 8($sp)
li $s2, 4 #j = 5
li $s1, 0 #i = 0
outer_loop:
addi $s2, $s2, -1 #i = j - 1
blt $s2, $zero, exit_sort
inner_loop:
bgt $s1, $s2, outer_loop #if i > j - 1
lw $s3, 0($a0) #load into s3 the a[i]
lw $s4, 4($a0) #load into s4 the a[i+1]
bgt $s3, $s4, swap #if a[i] > a[i+1]
addi $s1, $s1, 1 #i++
j inner_loop
swap: move $s0, $s3 #tmp = a[i]
move $s3, $s4 #a[i] = a[i+1]
move $s4, $s0 #a[i+1] = tmp
addi $a0, $a0, 4 #point to the next element ????
addi $s1, $s1, 1 #i++
j inner_loop
exit_sort:
lw $s0, 0($sp)
lw $s1, 4($sp)
lw $s2, 8($sp)
addi $sp, $sp, 8
move $v0, $a0 #pass into v0 the sorted array
jr $ra
.data
.align 2
array: .space 20
in_prompt: .asciiz "Enter 5 numbers:\n"
num_prompt: .asciiz "Give number: "
search_q: .asciiz "what are you looking for?\n"
not_found_pr: .asciiz " not found in array: \n"
found_pr: .asciiz " found in array: \n"