.data
prompt1: .asciiz "\n\n Enter an integer please:"
array: .space 24
linefeed: .asciiz "\n"
enterkey: .asciiz "Press any key to end program."
.text
main:
li $s0, 0
for:
bge $s0, 6, end_for
li $v0, 4 #syscall to print string
la $a0, prompt1 #address of string to print
syscall
li $v0, 5 #syscall to read an integer
syscall
move $t1,$v0
sw $t1,array($t0) #save the number to read into array
addi $t0,$t0,4
addi $s0,$s0,1
j for
end_for:
# print out a line feed
li $v0,4 # code for print_string
la $a0,linefeed # point $a0 to linefeed string
syscall # print linefeed
# wait for the enter key to be pressed to end program
li $v0,4 # code for print_string
la $a0,enterkey # point $a0 to enterkey string
syscall # print enterkey
# wait for input by getting an integer from the user (integer is ignored)
li $v0,5 # code for read_int
syscall #get int from user --> returned in $v0
# All done, thank you!
li $v0,10 # code for exit
syscall # exit program
this is my code.I am trying to store 6 integers in an array and then read again the array of integers and sum them and then printing the sum.I apologize for my bad english
It would be basically the same loop you have just written, but instead of writing the number to the array you would have to read it from the array and sum the values.
E.g.:
li $s0, 0
li $a0, 0
li $t0, 0
forsum:
bge $s0, 6, end_forsum
lw $t1,array($t0) # Load the number from array
addu $a0, $a0, $t1 # Compute the sum
addi $t0,$t0,4
addi $s0,$s0,1
j forsum
end_forsum:
li $v0,1
syscall # Print sum
You can also compute the sum while reading the values from the user input...
Related
I am attempting to recreate a C-snippet in assembly. The C program essentially:
creates a char array[256] along with a pointer *A initialized to NULL.
User input of some string is then stored into the char array
while each ith element of the array != 0
check it the ith element is == some DEFINED char value V.
If array[i] == V -> set A = &array[i]
break
Lastly check if A is still initialized to NULL
if not pint address and value of A
else not found
Unfortunately, when I run the MIPS code with Qtspim I get the aforementioned error Exception occurred at PC=0x004000a8
-> (Abort after)
-> Followed by Unaligned address in inst/data fetch: 0x1001012b
I feel like it has something to do with the way that I store my byte values in the array or the way I am accessing those memory locations but I can't figure out what the problem is. Any insight that anyone can offer would be greatly appreciated. Happy holidays everyone!
Bellow is my assembly code:
# global functions aforementioned error
.globl main
# .text assembler directive
.text
# main
main:
# register map
# use $t0 for i
# use $t1 for NULL
# use $s0 for &inputArray[i]
# use $s1 for indexed array value
# use $s2 for the base address inputArray
# use $s3 for result
# use $t2 for constCharlwr
# Prompt user for input
la $a0, str1
li $v0, 4
syscall
# Get user input and store in input array
la $a0, inputArray
li $a1, 256
li $v0, 8
syscall
# set up registers
lb $t0, i
lb $t1, NULL
la $s2, inputArray
lb $s3, result
lb $t2, constCharlwr
li $s0, 0
add $s0, $s0, $s2 # s0 = &arrayA[i]
while: # while loop
add $s0, $s0, $t0 # base address + 1 byte
lb $s1, 0($s0) # load array index value into s1
beq $s1, $t1, outsideWhile # inputArray[i] != '\0'
if1:
bne $s1, $t2, outsideIf # check if inputArray[i] == e
move $s3, $s1 # if true copy s1(inputArray[i] into s3(result)
sb $s3, result
j outsideWhile
outsideIf:
addi $t0, $t0, 1
j while
outsideWhile:
if2:
beq $s3, $t1, else
# Print results
# Print string 2
lw $a0, str2
li $v0, 4
syscall
# Print address of result
la $a0, result
li $v0, 4
syscall
# Print next line
lb $a0, nextline
li $v0, 4
syscall
# Print string 3
lw $a0, str3
li $v0, 4
syscall
# Print result char value
lb $a0, result
li $v0, 4
syscall
# Print next line
lb $a0, nextline
li $v0, 4
syscall
j exitPrgm
else:
# Print No match
lw $a0, str4
li $v0, 4
syscall
# Exit the program by means of syscall.
exitPrgm:
li $v0, 10 # Sets $v0 to "10" to select exit syscall
syscall # Exit
# .data assembler directive
.data
inputArray: .space 256
constCharlwr: .byte 'e'
result: .byte 0
NULL: .byte 0
i: .byte 0
str1: .asciiz "Enter a word to search for letter e: \n"
str2: .asciiz "First match at address "
str3: .asciiz "The matching character is "
str4: .asciiz "No match found\n"
nextline: .asciiz "\n"
Ok, so I figured out my initial problem, I was not using la for my sys calls and once I fixed that I started getting the output that I wanted. The only problem now is I can figure out how to print the actual address of the result. Can someone help me with this.
New Code, Trying a few diffrent things to get the memory address but nothing seems to work.
# Prompt user for input
la $a0, str1
li $v0, 4
syscall
# Get user input and store in input array
la $a0, inputArray
li $a1, 255
li $v0, 8
syscall
# set up registers
lb $t0, i
lb $t1, NULL
la $s2, inputArray
lb $s3, result
lb $t2, constCharlwr
li $s0, 0
add $s0, $s0, $s2 # s0 = &arrayA[i]
while: # while loop
add $s0, $s0, $t0 # base address + 1 byte
lb $s1, 0($s0) # load array index value into s1
beq $s1, $t1, outsideWhile # inputArray[i] != '\0'
if1:
bne $s1, $t2, outsideIf # check if inputArray[i] == e
sb $s1, result
j outsideWhile
outsideIf:
addi $t0, $t0, 1
j while
outsideWhile:
if2:
beq $s1, $t1, else
# Print results
# Print string 2
la $a0, str2
li $v0, 4
syscall
# Print address of result
la $t9, result
li $t8, 4
li $t0, 0
#for:
# bge $t0, $t8 outsideFor
# add $t9, $t9, $t0
# lb $t7, 0($t9)
# sb $t7, resultAddr
# la $a0, resultAddr
# li $v0, 4
# syscall
# addi $t0, $t0, 1
# j for
#outsideFor:
sb 0($t9) resultAddr
la $a0, resultAddr
li $v0, 4
syscall
sb 1($t9) resultAddr
la $a0, resultAddr
li $v0, 4
syscall
sb 2($t9) resultAddr
la $a0, resultAddr
li $v0, 4
syscall
sb 3($t9) resultAddr
la $a0, resultAddr
li $v0, 4
syscall
# Print next line
la $a0, nextline
li $v0, 4
syscall
# Print string 3
la $a0, str3
li $v0, 4
syscall
# Print result char value
la $a0, result
li $v0, 4
syscall
# Print next line
la $a0, nextline
li $v0, 4
syscall
j exitPrgm
else:
# Print No match
la $a0, str4
li $v0, 4
syscall
I am new to MIPS and I wrote a basic format of what I think the code from the C file I wrote is the equivalent to of the MIPS.
My assignment is to convert the following C file which I wrote into a direct translation of what the MIPS is supposed to be. My current C code is :
#include <stdio.h>
int d2b(int d)
{
if(d == 0)
{
return;
}
else
{
return (d %2 + 10 * d2b(d/2));
}
}
int main()
{
int d = 99;
int b;
b = d2b(d);
printf("Input => %d \n", d);
printf("Output => %d ", b);
return;
}
So far I have the following :
.data
msg1 .asciiz “Number is “
msg2 .asciiz “\nConverted to \n“
.text
.globl main
main:
li $v0, 4
la $a0, msg1
syscall
li $v0, 5 #Exit syscall
syscall
add $a0, $v0, $zero
jal fact
add $a0, $v0, $zero
li $v0, 1
syscall
li $v0, 10
la $a0, msg2
syscall
fact:
li $t0 0 #load 0
beq $a0, $t0, skip #test n
li $v0 0
jr $ra
skip:
subu $sp, $sp, 32
sw $ra 20($sp)
sw $fp, 16($sp)
addiu $fp, $sp, 28
sw $a0, 0($fp) #save n
li $t1 2 #load 2
divu $a0 $t1 #n / 2
mfhi $t2 #remainder
mflo $t3 #quotient
move $a0, $t3 #n = quotient
addi $v0, $a1, 10
jal fact
lw $a0, 0($fp) #restore n
multu $v0, $a0
lw $ra, 20($sp)
lw $fp, 16($sp)
addiu $sp, $sp, 32
jr $ra
My main problem is not knowing how to use syscall and not really understand a recursive function in MIPS. Please point out my mistakes and errors!
your MIPS syscalls are in this section
li $v0, 4
la $a0, msg1
syscall
li $v0, 5 #Exit syscall
syscall
add $a0, $v0, $zero
jal fact
add $a0, $v0, $zero
li $v0, 1
syscall
li $v0, 10
la $a0, msg2
syscall
They are commented incorrectly
In a MIPS syscall $v0 holds the "syscall function" or in English, the service you want the operating system to perform. There's a table of them here.
$a0 will hold the first parameter passed to the call. To set this parameter, one technique is to add the input value to zero storing the result into $a0 That's why you have so many lines like this
add $a0, $v0, $zero # this adds $v0 to the number zero and storing in $a0
Finally, the syscalls you are using are (4 => print String, 5 => read integer, 1 => print integer, and 10 => exit)
So a properly commented example of your code would be
la $a0, msg1 # load string as parameter
li $v0, 4 # load operation "print string"
syscall # request "print string" for msg1
li $v0, 5 # load operation "read integer"
syscall # request "read integer"
add $a0, $v0, $zero # load the read integer into $a0
jal fact
add $a0, $v0, $zero # load the value of $v0 into $a0
li $v0, 1 # load operation "print integer"
syscall # request "print integer"
As you can see, my confusion comes not from your ability to use syscalls, but from your description of what you think you are using the syscalls to do.
You state you want to print a binary number like 01001010 from a decimal input. This typically involves breaking the decimal number down, in a loop, printing out a zero or one in each of the binary number places. As this would require a loop for each placeholder in the binary number, it doesn't seem that a single call to "print integer" would be possible (unless the input was limited to only the decimal '1' and '0', or the input is limited to such a small number that it's binary representation, represented in decimal format is less than max_int).
So for an input of 5, the desired output would be 101, and that would be 3 calls to print, in the order of '1', '0', '1'. I believe this approach of printing the digits in a loop will give you greater success, and will permit you to print every positive decimal number inputted.
In short, I think your command of syscall is fine, but you're still struggling with how to do loops and solve problems in assembly. Try to figure out how you would determine the digits in the needed order by hand, using a pencil and paper, and then attempt to code that into your program.
I am writing a program to take 10 numbers from user into .word. The program is:
.data
msg1: .asciiz"Ener the number: "
fibs: .word 0,0,0,0,0,0,0,0,0,0
.text
main:
li $t0, 0
loop: # (loop condition, TODO)
bgt $t0,9 ,exit
li $t1, 0 # i = 0
la $a0,msg1 # display prompt string
li $v0,4
syscall
li $v0,5 # read 1st integer into $t0
syscall
move $t2,$v0
lw $t2, fibs($t1) # fib = fibs[i]
addi $t1, $t1, 4 # i++ <= +4
j loop
exit:
move $a0,$t1 # output sum
li $v0,1
syscall
li $v0, 10 # exit the program
syscall
However, the loop never ends and continuously takes the input...I want it to stop and show me the numbers I have input after the 10 integers are entered
I've just started to learn MIPS, and as part of our assignment, I'm trying to save a counter value that runs inside a loop.
So, I was able to exit the loop, thanks to Michael. But now the counter will not increase, I noticed that it won't enter the incount label.
.text
.globl main
main:
# get string from user
la $a0, str1 # load the addr of the given string into $a0.
li $v0, 4 # 4 is the print_string syscall.
syscall # do the syscall.
li $v0, 8 # take in input
la $a0, buffer # load byte space into addr
li $a1, 10 # allot the byte space for the string
move $t0, $a0 # save the string into $to
syscall
# get char from user
la $a0, char1 # load the addr of the given char into $a0.
li $v0, 4 # 4 is the print_string syscall.
syscall # do the syscall.
li $v0, 8 # take in input
la $a0, buffer # load byte space into addr
li $a1, 10 # allot the byte space for the char
move $t1, $a0 # save the char into $t1
syscall
addi $s2, $zero,0 # s2 holds the counter
loop:
lb $t3, ($t0)
beq $t3, $t1, incount # go to incount if char was found
beqz $t3, exit # go to exit if we arrived to the end of the string
addi $t0, $t0, 1 # incrase t3 by 1
j loop # go to loop
incount:
addi $s2, $s2, 1 # increase the counter by 1
addi $t0, $t0, 1 # incrase char pos by 1
j loop # go back to loop
exit:
la $a0, ($s2) # counter to be printed
li $v0, 1 # 1 is the print_int syscall.
syscall
li $v0, 10 # return control to SPIM OS
syscall
.data
buffer: .space 10
str1: .asciiz "Please enter your string: "
char1: .asciiz "Now, please enter your char of choice: "
# end countchar.s
Thanks in advance
You've placed your exit routine in the .data section, which is why you're getting the "invalid program counter value" error message. All code needs to be in the .text section.
I am doing my homework and it says that I have to ask user for how many members they want to be present in the array. Then the user should enter the number in their array and then the program prints the array. I cannot print contents from my array in the console window.
Here is my code:
.data
max: .word -9999
array: .space 12
message1: .asciiz "Enter an integer:\n"
message2: .asciiz "Specify how many numbers should be stored in the array (atmost 8): \n"
message3: .asciiz "The array content is: \n"
message4: .asciiz "The maximum is: \n"
message5: .asciiz "They have the same maximum.\n"
message6: .asciiz "The first array has a larger maximum.\n"
message7: .asciiz "The second array has a larger maximum.\n"
.text
.globl main
main:
lw $s1, max
la $s3, array
li $s2, 3
la $a0, message2
li $v0, 4
syscall
li $v0, 5
syscall
move $t0, $v0
blt $t0, $s2, Read
Read:
la $a0, message1
li $v0, 4
syscall
li $v0, 5
syscall
move $t1, $v0
sw $t1, 0($s3)
addi $s3, $s3, 4
addi $t0, $t0, -1
bgt $t0, $zero, Read
j Print
#blt $t0, $s2, Print
Print:
la $a0, message3,
li $v0, 4
syscall
jr $ra
Thanks for the help.
When you enter Print you've got the end of the array plus 4 in $s3, so you could do something like this:
$s2 = ADDRESSOF(array)
while ($s2 != $s3) do
print_int($s2[0]) // syscall 1
print_character(' ') // syscall 11
$s2 += 4
end while
This is pseudo-code to illustrate the logic; I'll leave the actual assembly implementation to you since it's your assignment.
(By the way, this: la $a0, message3, is a typo. There shouldn't be a comma at the end of that line)