ByBlackyDZN
ByBlackyDZN

Reputation: 1

MIPS Assembly Printing wrong value, but cant change 41 to 42

I'm working on a project right now, which should be written in MIPS using the Mars4_5 Assembler.

Here's the following code. I suppose it has something to do with the choice to use 41 in li $v0 41 instead of 42 but 42 just prints the following error message error Upper bound of range cannot be negative (syscall 42).

For this subtask, I have to generate random bits, using the testing file I added it should conclude in: 101100110110011101100110110011 Instead it prints: 111111111111111111111111111111.

    #vim:sw=2 syntax=asm
     .data
      random_id: .word 0 
         .globl main
     # Memory layout of the Configuration
     # |   eca  |   tape   |  tape_len  |  rule  |  skip  | column |
     # | 1 word |  1 word  |   1 byte   | 1 byte | 1 byte | 1 byte |
    automaton:
      .word 1       # eca
      .word 252     # tape
      .byte 8       # tape_len
      .byte 106     # rule
      .byte 1       # skip
      .byte 5       # column

    syscall_error_msg:
      .asciiz "Error: Random number generator syscall failed"
    
  
    .text
      .globl gen_byte, gen_bit
  
      main:

    # Arguments:
    #     $a0 : address of configuration in memory
    #   0($a0): eca       (1 word)
    #   4($a0): tape      (1 word)
    #   8($a0): tape_len  (1 byte)
    #   9($a0): rule      (1 byte)
    #  10($a0): skip      (1 byte)
    #  11($a0): column    (1 byte)

    # Return value:
    #  Compute the next valid byte (00, 01, 10) and put into $v0
    #  If 11 would be returned, produce two new bits until valid



    loopcounter:
      li $s0 30 # loop counter
    loop:
      beqz $s0 terminate
      subi $s0 $s0 1
      la $a0 automaton
      jal gen_bit
      # print returned value
      move $a0 $v0
      li $v0 1
      syscall
      j loop
     terminate:
      li      $v0 10
      syscall



    gen_byte:
    li $v0, 0

    gen_byte_loop:
    jal gen_bit
    move $t1, $v0 #moves v0 --> t1
    jal gen_bit
    or $t1, $t1, $v0

    #Check if 11 if so repeat
    beq $t1, $zero, gen_byte_end  #To end if not 11

    gen_byte_end:
    srl $t0, $t1, 1
    move $v0, $t0 

      jr $ra

# Arguments:
#     $a0 : address of configuration in memory
#   0($a0): eca       (1 word)
#   4($a0): tape      (1 word)
#   8($a0): tape_len  (1 byte)
#   9($a0): rule      (1 byte)
#  10($a0): skip      (1 byte)
#  11($a0): column    (1 byte)
#
# Return value:
#  Look at the field {eca} and use the associated random number generator to generate one bit.
#  Put the computed bit into $v0

gen_bit:
  li $v0, 41       # 41 = Random Number
  lw $a0, random_id
  syscall
  
  # Check if syscall failed
  bltz $v0, syscall_failed
  
  # Least significant bit
  andi $v0, $v0, 1
  jr $ra

syscall_failed:
  # Print error message or take appropriate action
  # For example:
  li $v0, 4   # syscall for printing string
  la $a0, syscall_error_msg
  syscall
  
  # Exit program
  li $v0, 10
  syscall

Upvotes: 0

Views: 92

Answers (1)

Erik Eidt
Erik Eidt

Reputation: 26696

That code assumes that syscall #41 returns the random number in $v0, which would be normal, but it doesn't — strange as it is, syscall #41 returns the random number in $a0.

Upvotes: 2

Related Questions