.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
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!