1

I want to write a program using loops that prints the asterisk character '*' five times, so I wrote this:

.data
ast: .word '*'

.text
.globl main
main:
la  $a0, ast
add $t0, $zero, $zero   #counter

loop:

slti    $t1, $t0, 5
beq     $t1, $zero, exit

li  $v0, 1
syscall

addiu   $t0, $t0, 1

j loop
exit:

li  $v0, 10
syscall

but instead of printing five asterisks, it gives me this huge number: 268500992268500992268500992268500992268500992

By running step by step I see that $t0 that I use for the counter has the correct value for each loop (1 to the 2 to the 3 to the 4 to the 5). With the slti and beq lines I try to control the loops till the counter reaches the number 5.

What is it missing?

Coursal
  • 1,387
  • 4
  • 17
  • 32
  • It is probably the `syscall`. The "huge number" is actually `268500992` printed 5 times. Sorry but I don't know the syscalls. – Weather Vane Oct 31 '16 at 10:20
  • 2
    You're using syscall #1 (print integer) when you should be using syscall #11 (print character). See: http://courses.missouristate.edu/KenVollmar/MARS/Help/SyscallHelp.html – Paul R Oct 31 '16 at 10:21
  • 1
    In hexadecimal that number is `10010000` so I will take a shot and guess you are printing the label address, not the asterisk character which is there. – Weather Vane Oct 31 '16 at 10:22
  • @PaulR I changed it to 11 but it prints nothing – Coursal Oct 31 '16 at 17:49
  • @WeatherVane how do i print the asterisks? – Coursal Oct 31 '16 at 17:50
  • I never wrote actually in MIPS but I guess you would have to load the data from that address into a register. Read up on #11 and see if it needs the actual character to print, or its *address*. I guess the former. 'fraid I don't know the syntax well enough. Perhaps @PaulR knows. – Weather Vane Oct 31 '16 at 17:58
  • I got it running by changing the "la $a0, ast" to "la $a0, '*'". Thank you so much for your precious help! – Coursal Oct 31 '16 at 18:07

1 Answers1

2

There are two problems with your code. Firstly in data declarations the asterisk should be decaled as .asciiz instead of .word. The .word data type is used for integers usually as it is 32 bits long. Secondly, you have used the wrong syscall to print the aesterick. li $v0, 1 is for printing integers. The correct one to be used here is li $v0, 4.

.data
ast: .asciiz "*"

.text
.globl main
main:
la  $a0, ast
add $t0, $zero, $zero   #counter

loop:

slti    $t1, $t0, 5
beq     $t1, $zero, exit

li  $v0, 4
syscall

addiu   $t0, $t0, 1

j loop
exit:
li  $v0, 10
syscall

The above code prints 5 *. Hope this helped. Cheers!

samia_azim
  • 36
  • 4
  • 1
    Fun fact: `.word '*'` is unusual but actually equivalent to `.asciiz "*"` / `.byte 0,0` (i.e. 2 extra bytes of zeros). Also, even better would be using the v0=11 print_char syscall, with `li $a0, '*'`, or write a loop to store asterisks into a buffer for one print-string syscall like in [this question](https://stackoverflow.com/questions/40471729/assembly-mips-nested-loops/66822239#66822239) about printing multiple rows of asterisks. – Peter Cordes Mar 27 '21 at 19:07