How do i go through a binary heap in MIPS?

94 Views Asked by At

.data

decoder_heap: .asciiz "_ETIANMSURWDKGOHVF*L*PJBXCYZQ**54*3***2&*+****16=/***(*7***8*90"
str_eingabe: .asciiz "morse_in:"
str_ausgabe: .asciiz "\ntext_out: "
str_rueckgabewert: .asciiz "\nRueckgabewert: "
buf_out: .space 256

.text

.eqv SYS_PUTSTR 4
.eqv SYS_PUTCHAR 11
.eqv SYS_PUTINT 1
.eqv SYS_EXIT 10

main:
    
    li $v0, SYS_PUTSTR
    la $a0, str_eingabe
    syscall

    li $v0, SYS_PUTSTR
    la $a0, test_msg
    syscall
    
    li $v0, SYS_PUTSTR
    la $a0, str_rueckgabewert
    syscall

    move $v0, $zero


    la $a0, decoder_heap
    la $a1, test_msg
    la $a2, buf_out
    jal morse
    
    
    move $a0, $v0
    li $v0, SYS_PUTINT
    syscall
    
    li $v0, SYS_PUTSTR
    la $a0, str_ausgabe
    syscall
    
    li $v0, SYS_PUTSTR
    la $a0, buf_out
    syscall

    
    li $v0, SYS_EXIT
    syscall

.data

test_msg: .asciiz ".... .- .-.. .-.. ---"

.text

morse:

    lb $t0, 0($a1)
    
    beq $t0, '\0', exit

decoderLoop:

    lb $t0, 0($a1)
    
    beq $t0, ' ', positionInHeap
    beq $t0, '\0', positionInHeap
    
    #
    
    beq $t0, '.', isDot
    beq $t0, '-', isDash
    
    j exit
    
isDot:

    #
    
    addi $a1, $a1, 1
    j decoderLoop

isDash:

    #
    
    addi $a1, $a1, 1
    j decoderLoop


positionInHeap: blt $a0, 63, positionInHeap

    lb $t1, 0($a0)
    sb $t1, 0($a2)
    
    addi $a1, $a1, 1
    addi $a2, $a2, 1
    addi $v0, $v0, 1
    
    j morse

exit:
    
    jr $ra
    

So this is a home assignment, and I've come this far, but I am really struggling at one point. I've written this code in MIPS-Assembler and assembler is still pretty new to me. I've understood the basics of this language, but I've still got plenty to learn.

This code decodes a morse code into an ASCIIZ string output. We are not allowed to modify the code above the label "morse" (only "test_msg"), and we also have to use exactly those registers. So, I think my code could work if I could correctly locate the index in the "decoder_heap" for every dot and dash. The "decoder_heap" is a binary heap, and to select the left child of the current node, if a dot was read, one has to set k = 2k + 1. The same is true for the right node; if a dash was read, set k = 2k + 2, where k is the current index. I am completely confused with this k.

My first attempt was to add $a0 and $a0 in $a0 and add 1 for a dot and 2 for a dash. But I got an arithmetic overflow. I would really appreciate your help on this one. Many thanks in advance for considering my request.

I also thought to store $a0 + $a0 in a register, like $t2, but this still didn't work.

So this is the revised version:

morse:

    lb $t0, 0($a1)
    
    beq $t0, '\0', exit
    
    li $t2, 0
    
decoderLoop:

    lb $t0, 0($a1)
    
    beq $t0, ' ', positionInHeap
    beq $t0, '\0', positionInHeap
    
    add $t2, $t2, $t2
    
    addi $t2, $t2, 1
    
    beq $t0, '.', isDot
    beq $t0, '-', isDash
    
    j exit
    
isDot:
    
    addi $a1, $a1, 1
    j decoderLoop

isDash:

    add $t2, $t2, 1
    addi $a1, $a1, 1
    j decoderLoop


positionInHeap:
    
    add $a0, $a0, $t2

    lb $t1, 0($a0)
    sb $t1, 0($a2)
    
    addi $a1, $a1, 1
    addi $a2, $a2, 1
    addi $v0, $v0, 1
    
    j morse

exit:
    
    jr $ra
1

There are 1 best solutions below

0
checkchecker On
.data

test_msg: .asciiz ".... .- .-.. .-.. ---"

.text

morse: 

    lb $t0, 0($a1)
    
    beq $t0, '\0', exit 
    
    la $a0, decoder_heap 
    
    li $t2, 0 
    
    
decoderLoop:

    lb $t0, 0($a1)
    
    bge  $t2, 63, ignoreMorse
    
    
    beq $t0, ' ', positionInHeap
    beq $t0, '\0', positionInHeap
    
    add $t2, $t2, $t2
    
    addi $t2, $t2, 1
    
    beq $t0, '.', isDot
    beq $t0, '-', isDash
    
    j exit
    
isDot:
    
    addi $a1, $a1, 1
    j decoderLoop

isDash: 
    add $t2, $t2, 1
    addi $a1, $a1, 1
    j decoderLoop


positionInHeap: 
    
    add $a0, $a0, $t2 # Die Adresse des ASCIIZ Zeichens wird ermittelt

    lb $t1, 0($a0)
    sb $t1, 0($a2)
    
    addi $a1, $a1, 1 
    addi $a2, $a2, 1 
    addi $v0, $v0, 1 
    
    j morse
    
ignoreMorse: 

    addi $a1, $a1, 1
    
    j morse

exit: 
    
    jr $ra

So, the main issue was that I couldn't figure out how to index the decoder heap correctly. It turned out that I had to store and calculate the index separately. I also reset the index and the pointer for the following morse-code.

Thank you again for your help Jester!