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

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
^

Related

left most bit of a number mips

# 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

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

Mips code with PCspim exception 7

i have written a code that permutes a string in all its possible ways. The original code is in C++, and the task of the exercise is to implement the code in C++ in MIPS.For example, if you insert "abc" the result is [abc,acb,bca,bac,cba,cab]. So in C++ looks like this:
void Permutaciones(char * cad, int l) {
char c;
int i, j;
int n = strlen(cad);
for(i = 0; i < n-l; i++) {
if(n-l > 2) Permutaciones(cad, l+1);
else cout << cad << ", ";
c = cad[l];
cad[l] = cad[l+i+1];
cad[l+i+1] = c;
if(l+i == n-1) {
for(j = l; j < n; j++) cad[j] = cad[j+1];
cad[n] = 0;
}
}
}
and here's my code in MIPS
.data
str: .asciiz "abc"
coma: .asciiz ", "
.text
main:
la $a0, str
li $a1, 0
jal perm
li $v0, 10
syscall
length:
lb $t0, 0($a0)
beq $t0, $0, preperm
addi $v0, $v0, 1
addi $a0, $a0, 1
j length
preperm:
subu $a0, $a0, $v0
jr $ra
perm:
subu $sp, $sp, 32
sw $ra, 0($sp) #salvo ra
sw $a0, 4($sp) #salvo cad
sw $a1, 8($sp) #salvo L
jal length
sw $v0, 12($sp) #salvo n
subu $v0, $v0, $v0
lw $a0, 4($sp) #rescato cad
lw $a1, 8($sp) #rescato L
lw $t0, 12($sp) #rescato n
li $t2, 0 #$t2=i=0
for1:
sub $t1, $t0, $a1 # $t1= n- L
bge $t2, $t1, fin1 # i >= n- L => fin1
li $t3, 2 # $t3=2 (constante)
bgt $t1, $t3, recursion #n-L >2 => recursion
mostrar:
li $v0, 4
syscall
la $a0, coma
syscall
subu $v0, $v0, $v0
jal nomostrar
recursion:
sw $t2, 16($sp) #salvo i
addi $a1, $a1, 1 #l++
jal perm #recurso
nomostrar:
lw $a0, 4($sp) #rescato cad
lw $a1, 8($sp) #rescato L
lw $t0, 12($sp) #rescato n
lw $t2, 16($sp) #rescato i
add $t4, $a0, $a1 #$t4 = direccion cad[L]
lb $t5, 0($t4) #$t5=cad[L]
add $t6, $a0, $a1
add $t6, $t6, $t2
addi $t6, $t6, 1 #$t6=direccion cad [L+i+1]
lb $t7, 0($t6) #$t7 = cad [L+i+1]
sb $t7, 0($t4)
sb $t5, 0($t6) #swap (cad[L],cad [L+i+1])
add $t7, $a1, $t2 #$t7 = L+i
subu $t5, $t0, 1 #$t5 = n-1
bne $t7, $t5, cola #L+i != n-1 => cola
or $t8, $a1, $0 #t8= j = L
for2:
bge $t8, $t0, cola # j >= n => cola
add $t5, $a0, $t8 #$t5 = dirección de cad[j]
addi $t1, $t5,1 #$t1 = dirección de cad[j+1]
lb $t7, 0($t1) #$t7 = cad[j+1] propiamente dicho
sb $t7, 0($t5) # cad[ j ] = cad[j+1]
addi $t8, $t8, 1 # j++
j for2 # repetir
cola:
add $t8, $a0, $t0 #$t8 = dirección de cad[n]
sb $0, 0($t8) # cad[n] = '\0'
addi $t2, $t2, 1 # i++
sw $t2, 16($sp)
j for1 # repetir
fin1:
lw $ra, 0($sp) #rescato ra
sw $0, 16($sp)
addi $sp, $sp,32 #libero memoria
jr $ra #retorno
So, the problem is that when i run the program in PCspim using F5 i get the first output "abc" then i get Exception 7 Bad data address two times, and then it shows some more letters of the string. But when I use the step by step function (F10), the code works perfectly. Please someone help me, because i`m losing my mind.

Drawing on MIPS. Runtime error

have a problem with the following code. I wrote a code for drawig a quater circle on a MARS assembler. But there is an error occurring. The program itself draws the quater circle but in the end there is an error, because of it I cannot use a loop for this procedure, the code is below
.data
DISPLAY: .space 65536
DISPLAYWIDTH: .word 128
DISPLAYHEIGHT: .word 128
.text
j main
set_pixel_color:
mulu $t0 $a1 $s0
add $t0 $t0 $a0
mul $t0 $t0 4
la $t2 DISPLAY
add $t2 $t2 $t0
sw $a2 ($t2)
jr $ra
quater_circle:
add $a1 $0 0
add $a0 $0 0
lw $a2 RED
loop2:
jal set_pixel_color
add $a0 $a0 1
mulu $t3 $a0 $a0
mulu $t4 $a1 $a1
add $t3 $t3 $t4
mulu $t4 $a3 $a3
ble $t3 $t4 loop2
add $a0 $0 $0
add $a1 $a1 1
ble $a1 $a3 loop2
jr $ra
.data
RED: .word 0xff0000
GREEN: .word 0x00ff00
BLUE: .word 0x0000ff
.text
main:
lw $s0, DISPLAYWIDTH # s0 holds MAX x
lw $s1, DISPLAYHEIGHT # s1 holds MAX y
li $a3 1
lw $a2 BLUE
add $a0 $0 $0
add $a1 $0 $0
loop:
jal set_pixel_color
add $a0 $a0 1
ble $a0 127 loop
add $a0 $0 $0
add $a1 $a1 1
ble $a1 127 loop
draw:
jal quater_circle
add $a3 $a3 1
ble $a3 128 draw
It ends up with the drawn red quater circle with the blue backround, however it terminates in the end of the procedure, and I cannot use a draw procedure. Can you help me please?
You are losing $ra in your quater_circle subroutine.
That routine is called from main and it calls another subroutine (set_pixel_color), thus losing original return address.
You should preserve $ra in your quater_circle subroutine by storing its contents into the stack (and restoring it before returning to the caller) or alternatively moving $ra to some other register (e.g, $s2) and use it to return.
For the second alternative, you would add
move $s2, $ra
at the beginning of quater_circle subroutine and change
jr $ra
with
jr $s2
at the end of the subroutine.

C++ code into MIPS, the code in MIPS runs without error messages, but does not display results

The assignment asked us to complete a code in MIPS. The initial MIPS code needed a function we had to translate from a C++ code. I translated the function from C++ to MIPS as required.
The code in MIPS does not display any errors when I run it. However, the code does not display anything.
I tried to debug it, but I still don't see where the problem is. I am using Notepad++ as an editor and QtSpim to run the MIPS code. I posted the code(in C++ first, then in MIPS) bellow. Your help will be appreciated.
//*************C++ Code***********************
#include <stdio.h>
void update(float *, float *);
int main()
{
float x[5] = {.1, .2, .4, .6, .85};
float vx[5] = {-.2, -.15, .05, -.2, .2};
int i, steps;
for (i=0; i<5; i++)
{
printf("%d %f %f\n", i, x[i], vx[i]);
}
for (steps=0; steps<3; steps++)
{
update(x, vx);
printf("Step %d\n", steps);
for (i=0; i<5; i++)
{
printf("%d %f %f\n", i, x[i], vx[i]);
}
}
}
void update(float pos[], float vel[])
{
int i;
for (i=0; i<5; i++)
{
pos[i] += vel[i];
if (pos[i] < 0.)
{
pos[i] = 0.;
vel[i] = - vel[i];
}
else if (pos[i] > 1.)
{
pos[i] = 1.;
vel[i] = - vel[i];
}
}
}
//************************End of C++ Code*************************
//**************************Code Translated in MIPS*************
.data
x: .float 0.1
.float 0.2
.float 0.4
.float 0.6
.float 0.85
vx: .float -0.2
.float -0.15
.float 0.05
.float -0.2
.float 0.2
zero: .float 0.
one: .float 1.
space: .asciiz " "
endl: .asciiz "\n"
outStep:.asciiz "Step "
# i $s0
# steps $s1
# &x[0] $s2
# &vx[0] $s3
.globl for
.text
main: la $s2, x
la $s3, vx
move $t2, $s2
move $t3, $s3
li $s0, 0 # for (i=0; i<5; i++) {
ploop: move $a0, $s0 # printf("%d %f %f\n", i, x[i], vx[i]);
li $v0, 1
syscall
la $a0, space
li $v0, 4
syscall
l.s $f12, ($t2)
li $v0, 2
syscall
la $a0, space
li $v0, 4
syscall
l.s $f12, ($t3)
li $v0, 2
syscall
la $a0, endl
li $v0, 4
syscall
addi $t2, $t2, 4
addi $t3, $t3, 4
addi $s0, $s0, 1 # }
blt $s0, 5, ploop
li $s1, 0 # for (steps=0; steps<3; steps++) {
loop: move $a0, $s2 # update(x, vx);
move $a1, $s3
jal update
la $a0, outStep # printf("Step %d\n", steps);
li $v0, 4
syscall
move $a0, $s1
li $v0, 1
syscall
la $a0, endl
li $v0, 4
syscall
move $t2, $s2
move $t3, $s3
li $s0, 0 # for (i=0; i<5; i++) {
ploop1: move $a0, $s0 # printf("%d %f %f\n", i, x[i], vx[i]);
li $v0, 1
syscall
la $a0, space
li $v0, 4
syscall
l.s $f12, ($t2)
li $v0, 2
syscall
la $a0, space
li $v0, 4
syscall
l.s $f12, ($t3)
li $v0, 2
syscall
la $a0, endl
li $v0, 4
syscall
addi $t2, $t2, 4
addi $t3, $t3, 4
addi $s0, $s0, 1
blt $s0, 5, ploop1
addi $s1, $s1, 1
blt $s1, 3, loop
li $v0, 10
syscall
# void update(float pos[], float vel[]) {
# arg0 $a0
# arg1 $a1
# i $s0
update: l.s $f30, zero
l.s $f31, one
# The function i translated in MIPS is right bellow
addi $s0,$s0,0 # i=0
add.s $f0, $f0, $f1 # pos[i] += vel[i];
c.lt.s $f0, $f30 # if (pos[i] < 0.) {
bc1f else
add.s $f0, $f0, $f30 # pos[i]=0;
sub.s $f1, $f30 , $f1
sub.s $f31, $f30, $f31
add.s $f1, $f1, $f31 # vel[i] = - vel[i];
blt $s0, 5, update
else : c.lt.s $f31, $f0 #else if (pos[i] > 1.) {
bc1f skip
add.s $f0, $f0, $f31
sub.s $f31, $f30, $f31
sub.s $f1, $f1, $f31
blt $s0, 5, update
skip : add $s0, $s0, 0
addi $s0, $s0, 1
slti $t1, $s0, 5
blt $s0, 5, update
end: jr $31 #}
I tried it in PCSpim, but changed .globl for to .globl main. Now there is output, but your update function doesn't work yet as expected. You use $f0 and $f1, but these are never loaded or stored, so there is no update.