left most bit of a number mips - bit-manipulation

# 1 - Request a number
# 2 - Read the number
# 3 - Display Binary msg
# 4 - Display the number as binary
# 5 - Find the left-most bit (loop)
# 6 - Display the result msg
# 7 - Display the position
.data
prompt: .asciiz "Enter a 16 bit number: "
binaryMsg: .asciiz "\nBinary: "
results: .asciiz "\nThe left most bit is in position(zero based): "
.text
.globl main
main:
li $v0, 4
la $a0, prompt
syscall
li $v0, 5
syscall
move $a1, $v0
li $v0, 4
la $a0, binaryMsg
syscall
jal prtbin
# New Line
li $v0, 11
li $a0, 10
syscall
jal main
prtbin:
add $t0, $zero, $a1 # put our input ($a1) into $t0
add $t1, $zero, $zero # Zero out $t1
addi $t3, $zero, 1 # load 1 as a mask
sll $t3, $t3, 15 # move the mask to appropriate position
addi $t4, $zero, 16 # loop counter
loop:
and $t1, $t0, $t3 # and the input with the mask
beq $t1, $zero, print # Branch to print if its 0
add $t1, $zero, $zero # Zero out $t1
addi $t1, $zero, 1 # Put a 1 in $t1
j print
print:
li $v0, 1
move $a0, $t1
syscall
srl $t3, $t3, 1
addi $t4, $t4, -1
bne $t4, $zero, loop
li $v0, 4
la $a0, results
syscall
li $v0, 10
syscall
I'm building a program that takes a 16 bit number converts it to binary and gets the left most bit and outputs that position of it. I'm having two issues one being I cant seem to get it work without looping back to the main and cant seem to get the left most bit and output that into the results. any help will be much appreciated.
update
I figured out how to get it from looping but now I still cant seem to find out how to get the left most bit and display that

Related

why jal main error (jal 0x00000000 [main])

When I run this code,There is an error in the main and it does not operate normally.
I changed the main function or thought there was a problem with the main and global main, so I repeated the correction several times.
.data
message: .asciiz " The final result is "
.text
.global main
main:
addi $a0, $zero, 3
addi $a1, $zero, 10
addi $a2, $zero, 15
addi $a3, $zero, 7
jal leaf_example
li $v0, 4
la $a0, message
syscall
li $v0, 1
syscall
leaf_example:
addi $sp, $sp,-12
sw $t1, 8
sw $t0, 4
sw $s0, 0
add $t0,$a0,$a1
add $t1,$a2,$a3
sub $s0,$t0,$t1
add $v0,$s0,$zero
lw $s0,0
lw $t0,4
lw $t1,8
addi $sp,$sp,12
jr $ra
spim: (parser) syntax error on line 4 of file
C:/Users/user/Desktop/qtspim16.asm .global main
^

How to write int to file in MIPS?

I'm doing a homework where I have to read a non-fixed numbers of integers separated by \n from a text file and sort them in a linked list (and in an array, to compare performance). After that, I have to write the sorted list into another text file, and that's where my problem is. I don't really know how syscall 15 works (write to file). I don't know what kind of input it would print to the file. I mean, I'm guessing they have to be strings, not integers... so I made a little test program and it didn't work. Here it is:
.data
archivo: .asciiz "salida.txt"
.text
# reservar memoria para 3 chars + \0
li $v0, 9
li $a0, 4
syscall
move $s0, $v0
# agregar al array el numero 1 ascii
addi $t0, $zero, 49
sw $t0, 0($s0)
addi $s0, $s0, 4
# agregar al array el numero 0 ascii
addi $t0, $zero, 48
sw $t0, 0($s0)
addi $s0, $s0, 4
# agregar al array el numero 0 ascii
addi $t0, $zero, 48
sw $t0, 0($s0)
addi $s0, $s0, 4
# agregar al array \0 al final
addi $t0, $zero, 0
sw $t0, 0($s0)
addi $s0, $s0, -12
# abrir archivo en modo lectura
li $v0, 13
la $a0, archivo
li $a1, 1
li $a2, 0
move $s1, $v0
syscall
# escribir buffer $s0 en el archivo
li $v0, 15
move $a0, $s1
move $a1, $s0
addi $a2, $zero, 4
syscall
# cerrar archivo
li $v0, 16
move $a0, $s1
syscall
# finalizar ejecucion
li $v0, 17
syscall
I tried to allocate enough memory for 3 chars + \0 char, in order to write the number 100 to the file "salida.txt". So, I stored the ascii values of 1, 0, 0 into an array (which is the allocated memory), and then decrement the pointer, to point to the beginning of that memory block. After that, I open the file in write-mode and write 4 characters of the buffer $s0.
Unfortunately, this only creates the file but writes nothing in it. Any help would be appreciated. Thanks.
I also tried writing a variable declared in .data, like this:
.data
hola: .asciiz "hola"
.text
la $s3, hola
...
# do syscall 15 with move $a1, $s3
but this didn't work either.
Turns out you need to store the numbers as bytes in the array you want to print. So, if you want to write a number, you store its ascii number as byte using "sb". I used a little example I found online and modified it to my testing needs. I stored a number backwards in an array and wrote that to a file.
.data
fout: .asciiz "testout.txt" # filename for output
.text
# allocate memory for 3 chars + \n, no need to worry about \0
li $v0, 9
li $a0, 4 # allocate 4 bytes for 4 chars
syscall
move $s0, $v0
addi $s0, $s0, 3 # point to the end of the buffer
li $t3, 10 # end line with \n
sb $t3, 0($s0)
addi $s0, $s0, -1
# start witing the number 100 backwars. ascii_to_dec(48) = 0, ascii_to_dec(49) = 1
li $t3, 48
sb $t3, 0($s0)
addi $s0, $s0, -1 # move the pointer backwards, meaning you go from the end to the beginning
li $t3, 48
sb $t3, 0($s0)
addi $s0, $s0, -1
li $t3, 49
sb $t3, 0($s0)
# Open (for writing) a file that does not exist
li $v0, 13 # system call for open file
la $a0, fout # output file name
li $a1, 1 # Open for writing (flags are 0: read, 1: write)
li $a2, 0 # mode is ignored
syscall # open a file (file descriptor returned in $v0)
move $s6, $v0 # save the file descriptor
# Write to file just opened
li $v0, 15 # system call for write to file
move $a0, $s6 # file descriptor
move $a1, $s0 # address of buffer from which to write
li $a2, 4 # hardcoded buffer length
syscall # write to file
# Close the file
li $v0, 16 # system call for close file
move $a0, $s6 # file descriptor to close
syscall # close file

How to compare values within registers in MIPS?

I am trying to create a function that prompts the user to enter a number between 3 and 30 and if the number is less than 3 it will display "your number is less than 3", and if the number is greater than 30 it will display "your number is greater than 30". This may be dumb but I am new to MIPS and I don't quite understand what I am doing wrong.
Thank you
.data
prompt: .asciiz "Enter your number (3-30):"
message: .asciiz "\n Your number is "
message2: .asciiz "\n Your number is less than 3"
message3: .asciiz "\n Your number is more than 30"
.text
# Prompt the user to enter the number
li $v0, 4
la $a0, prompt
syscall
# Get the number
li $v0, 5 #get an integer from the user
syscall
# Store the result in t0
move $t0, $v0
main: #syscall to end the program
addi $t1, $zero, 0
addi $t2, $zero, 3
addi $t3, $zero, 30
ble $t0, $t1, numberSmaller
bge $t0, $t2, numberLarger
li $v0, 10
syscall
numberSmaller:
li $v0, 4
la $a0, message2
syscall
numberLarger:
li $v0, 4
la $a0, message3
syscall
You were actually pretty close.
The main: label is in the wrong place, so under some simulators, the first few instructions may not be executed.
Also, the program is [somewhat] incomplete because after the conditional branch is taken, the program "falls off the end of the world".
But, the core of the problem is the two branches need different branch conditions and the second register in each needs to be changed:
Change:
ble $t0, $t1, numberSmaller
Into:
blt $t0, $t2, numberSmaller
Change:
bge $t0, $t2, numberLarger
Into:
bgt $t0, $t3, numberLarger
So, here's the fully corrected program:
.data
prompt: .asciiz "Enter your number (3-30):"
message: .asciiz "\n Your number is "
message2: .asciiz "\n Your number is less than 3"
message3: .asciiz "\n Your number is more than 30"
.text
.globl main
main:
# Prompt the user to enter the number
li $v0,4
la $a0,prompt
syscall
# Get the number
li $v0,5 # get an integer from the user
syscall
# Store the result in t0
move $t0,$v0
addi $t1,$zero,0
addi $t2,$zero,3
addi $t3,$zero,30
blt $t0,$t2,numberSmaller
bgt $t0,$t3,numberLarger
# output message to show the number
li $v0,4
la $a0,message
syscall
# show the number
li $v0,1
move $a0,$t0
syscall
exit:
li $v0,10 # syscall to end the program
syscall
numberSmaller:
li $v0,4
la $a0,message2
syscall
j exit
numberLarger:
li $v0,4
la $a0,message3
syscall
j exit
Here's a slightly tighter version:
.data
prompt: .asciiz "Enter your number (3-30):"
message: .asciiz "\n Your number is "
message2: .asciiz "\n Your number is less than 3"
message3: .asciiz "\n Your number is more than 30"
.text
.globl main
main:
# Prompt the user to enter the number
li $v0,4
la $a0,prompt
syscall
# Get the number
li $v0,5 # get an integer from the user
syscall
# Store the result in t0
move $t0,$v0
li $t1,3
blt $t0,$t1,numberSmaller
li $t1,30
bgt $t0,$t1,numberLarger
# output message to show the number
li $v0,4
la $a0,message
syscall
# show the number
li $v0,1
move $a0,$t0
syscall
exit:
li $v0,10 # syscall to end the program
syscall
numberSmaller:
li $v0,4
la $a0,message2
syscall
j exit
numberLarger:
li $v0,4
la $a0,message3
syscall
j exit

If greater than or equal in MIPS

Prompt for and input two integers “a” and “b” using syscalls
Display one of the following statements depending on if a>b, or a=b or a
You entered a greater than b
You entered an equal to b
You entered a less than b
I have to get this prompt and I tried so hard to get it done. This is where I'm stucked, I'd really appreciate your help.
.data
p1: .asciiz "Please enter the first number ? "
p2: .asciiz " Please enter the second number? "
ans1: .asciiz " \nYou entered a greater than b "
ans2: .asciiz " \nYou entered a equal to b "
ans3: .asciiz " \nYou entered a less than b "
.text
.globl main
main:
li $v0, 4 #system call code for print_str
la $a0, p1 #address of string to print
syscall #print the first prompt
li $v0, 5 #system call code for read_int
syscall #read first integer
move $t1, $v0 #store it till later
li $v0, 4 #system call code for print_str
la $a0, p2 #address of string to print
syscall #prints the second prompt
li $v0, 5 #system call code for read_int
syscall #read first integer
move $t2, $v0 #store it till later
slt $t1,$s1,$s0 # checks if $s0 > $s1
beq $t1,1,label1
I really don't know how to use branch statements, and it's really confusing. I would like to know how to fix it.
Why do you read the numbers into $t1 and $t2 then compare $s1 and $s0? Where is it confusing?
Simply use slt and beq/bne, that'll cover all comparison cases you need.
Suppose a is in $s0, b is in $s1
a < b:
slt $t0, $s0, $s1
bne $t0, $zero, a_lt_b # $t0 == 1 != 0 if a < b
a = b:
beq $s0, $s1, a_eq_b # nothing more to explain
a > b:
slt $t0, $s1, $s0
bne $t0, $zero, b_lt_a # $t0 == 1 != 0 if b < a
a >= b:
slt $t0, $s0, $s1
beq $t0, $zero, a_ge_b # $t0 == 0 if a >= b or !(a < b)
a <= b:
slt $t0, $s1, $s0
beq $t0, $zero, b_ge_a # $t0 == 0 if b >= a or !(b < a)

Translating c++ to MIPS assembly

I'm trying to convert the following line of C++ code to MIPS assembly:
cout << a2[i]
This is the code I've tried but I'm getting incorrect results.
*The variable i is saved in $t5.
li $v0, 1
la $a0, a2
sll $t5, $t5, 2
add $a0, $a0, $t5
srl $t5, $t5, 2
lw $a0, 0($a0)
syscall
I'm a little rusty when it comes to MIPS. However, I do remember some things.
You generally shouldn't use the $a registers unless you're passing arguments to a function (as you do with syscall).
So, in these two cases, I would use temporary registers instead:
la $a0, a2
add $a0, $a0, $t5
becomes
la $t0, a2
add $t1, $t0, $t5
and then:
lw $a0, 0($t1)
syscall
And you can probably omit this as well:
srl $t5, $t5, 2
Other than that, I would ask what sort of incorrect output are you receiving?