MIPS $ ra адрес не выровнен по словам? - PullRequest
0 голосов
/ 17 января 2020

Я работаю над проектом для университетского экзамена, который заключается в шифровании сообщения с помощью простых алгоритмов, и я просто не понимаю, почему эта часть кода не работает.

Я называю encryptE процедура с инструкцией beq в основном, затем я перехожу к метке searchEquals с инструкцией jal, и внутри нее мне нужно вызывать другие процедуры ( intTOascii и stackPop ) .... по этой причине я должен сохранить адрес в $ra первого jal вызова в стеке, но когда я запускаю код с помощью mars выдает ошибку:

Исключение во время выполнения в 0x004002c0: адрес магазина не выровнен по границе слова 0x7fffeff7

Мне кажется, я понимаю, что это за ошибка, но я не понял, почему адрес в $ra нет выравнивания по словам

Единственное, что в некоторых процедурах я использовал стек для сохранения некоторых символов и извлечения их в обратном порядке с помощью инструкций lb и sb ионы .... но эти части кода должны появиться позже (например, в intTOascii ), и в любом случае это не должно вызывать проблем, так как все символы, которые я помещаю sh внутри, затем я выскакиваю из них

Я оставлю часть рассматриваемого кода ниже, две строки, которые дают мне ошибку, находятся почти внизу. Заранее спасибо за помощь:)

# Algoritmo di criptazione E
encryptE:   
    move $s6, $zero                     # inizializzamo in $s6 l'offset per il bufferTmp
    move $s7, $zero                     # inizializzamo in $s7 l'offset per il bufferMsg


    copyLoop:                           
        lb $s0, bufferMsg($s6)          # Carica in $s0 l'elemento del bufferMsg in posizione $s6

        beqz $s0, endCopy               # Se l'elemento in $s0 è 0 (ovvero il carattere ASCII [NULL]) si esce dal ciclo

        sb $s0, bufferTmp($s6)          # Copiamo l'elemento $s0 nel bufferTmp

        addi $s6, $s6, 1                # incrementiamo $s6 per andare a leggere il carattere successivo nella prossima iterazione
        j copyLoop                      # saltiamo allo statement copyLoop per iterare sul buffer

    endCopy:    
        move $s6, $zero                 # riinizializzamo in $s6 l'offset per il bufferMsg


    nextE:                                      
        lb $s0, bufferTmp($s6)          # Carica in $s0 l'elemento del bufferTmp in posizione $s6

        beqz $s0, endE                  # Se l'elemento in $s0 è 0 (ovvero il carattere ASCII [NULL]) si esce dal ciclo

        jal checkDuplicate              # salto jal a checkDuplicate che controlla che il carattere in $s0 non sia gia presente nel bufferMsg

        sb $s0, bufferMsg($s7)          # nel caso $s0 non sia già presente nel bufferMsg lo inseriamo
        addi $s7, $s7, 1                # incrementiamo di un byte l'offset $s7

        move $a0, $s6                   # creiamo una copia dell'offset $s6 e la passiamo come argomento a searchEquals attraverso il registro $a0

        jal searchEquals                # salto jal a searchEquals che scandisce il buffer per trovare tutte le posizioni del carattere in esame

    adef:

    skip:                               # label di ritorno da checkDuplicate nel caso il carattere sia già presente nel buffer
        addi $s6, $s6, 1                # incrementiamo $s6 per andare a leggere il carattere successivo nella prossima iterazione
        j nextE                         # saltiamo allo statement nextE per iterare sul buffer

    endE:       
        j return                        # torniamo allo statement return della procedura chiamante  


    checkDuplicate:     
        move $t7, $zero                 # inizializzamo un offset per scandire bufferMsg dall'inizio

        startCheck:
            beq $s7, $t7, endCheck      # se $t7 = $s7 (offset principlae di bufferMsg) si esce dal ciclo

            lb $t0, bufferMsg($t7)      # Carica in $t0 l'elemento del bufferMsg in posizione $t7

            beq $s0, $t0, skip          # se $t0 = $s0 (carattere in esame), $s0 è gia nel buffer e si salta a skip
            addi $t7, $t7, 1            # incrementiamo di un byte l'offset $t7
            j startCheck                # saltiamo allo statement startCheck per iterare sul buffer

        endCheck:       
            jr $ra                      # saltiamo all'istruzione succesiava alla chiamata


    searchEquals:   
        lb $t0, bufferTmp($a0)          # Carica in $t0 l'elemento del bufferMsg in posizione $a0

        beqz $t0, endSearch             # Se l'elemento in $t0 è 0 (ovvero il carattere ASCII [NULL]) si esce dal ciclo

        beq $s0, $t0, regPosition       # se $t0 = $s0 (carattere in esame) si si salta a regPosition

        addi $a0, $a0, 1                # incrementiamo di un byte l'offset $a0
        j searchEquals                  # saltiamo allo statement searchEquals per iterare sul buffer

        regPosition:    
            addi $t1, $zero, 45         # salviamo in t1 la costante 45 (codice ASCII del carattere '-')
            sb $t1, bufferMsg($s7)      # inseriamo l'elemento $t1 nel bufferMsg    
            addi $s7, $s7, 1            # incrementiamo di un byte l'offset $s7

            ################################################
            # These are the two lines that give me the error
            ################################################

            addi $sp, $sp, -4           
            sw $ra, 0($sp)              # Runtime exception at 0x004002c0: store address not aligned on word boundary 0x7fffeff7

            jal intTOascii              

            jal stackPop

            addi $a0, $a0, 1
            j searchEquals

    endSearch:  
        addi $t0, $zero, 32
        sb $t0, bufferMsg($s7)
        addi $s7, $s7, 1

        lw $ra,3($sp)
        addi $sp,$sp,8
        jr $ra
...