Исключение произошло на ПК = 0x004000a8 -> (Прервать после) -> За которым следует невыровненный адрес в inst/data fetch: 0x1001012b

Я пытаюсь воссоздать C-фрагмент в сборке. Программа C по существу:

  • создает массив символов[256] вместе с указателем *A, инициализированным значением NULL.

  • Пользовательский ввод некоторой строки затем сохраняется в массив символов

  • в то время как каждый i-й элемент массива != 0

  • проверьте, что i-й элемент == некоторое значение DEFINED char V.

  • Если массив [i] == V -> установить A = &массив[i]

  • перемена

  • Наконец, проверьте, инициализирован ли A до NULL, если не указан адрес и значение A.

  • остальное не найдено

К сожалению, когда я запускаю код MIPS с Qtspim, я получаю вышеупомянутую ошибку. Исключение произошло на ПК = 0x004000a8 -> (Прервать после) -> За ним следует невыровненный адрес в inst/data fetch: 0x1001012b

Я чувствую, что это как-то связано с тем, как я храню значения байтов в массиве или как я обращаюсь к этим ячейкам памяти, но я не могу понять, в чем проблема. Любое понимание, которое кто-либо может предложить, будет принято с благодарностью. С праздником всех!

Ниже мой ассемблерный код:

# global functions aforementioned error
    .globl main 

# .text assembler directive
    .text       

# main
main:
    # register map 
    # use $t0 for i
    # use $t1 for NULL
    # use $s0 for &inputArray[i]
    # use $s1 for indexed array value
    # use $s2 for the base address inputArray
    # use $s3 for result
    # use $t2 for constCharlwr


# Prompt user for input
    la $a0, str1
    li $v0, 4
    syscall

# Get user input and store in input array

    la $a0, inputArray
    li $a1, 256
    li $v0, 8
    syscall

# set up registers
    lb $t0, i 
    lb $t1, NULL
    la $s2, inputArray
    lb $s3, result
    lb $t2, constCharlwr
    li $s0, 0
    add $s0, $s0, $s2  # s0 =  &arrayA[i]

    while:                           # while loop

        add $s0, $s0, $t0            # base address + 1 byte
        lb  $s1, 0($s0)              # load array index value into s1
        beq $s1, $t1, outsideWhile   # inputArray[i] != '\0'

        if1:
            bne  $s1, $t2, outsideIf # check if inputArray[i] == e 
            move $s3, $s1            # if true copy s1(inputArray[i] into s3(result)
            sb   $s3, result
            j outsideWhile
        outsideIf:
        addi $t0, $t0, 1
        j while

    outsideWhile:

        if2:
            beq $s3, $t1, else
            # Print results
            # Print string 2
            lw $a0, str2
            li $v0, 4
            syscall
            # Print address of result
            la $a0, result
            li $v0, 4
            syscall
            # Print next line
            lb $a0, nextline
            li $v0, 4
            syscall
            # Print string 3
            lw $a0, str3
            li $v0, 4
            syscall
            # Print result char value
            lb $a0, result
            li $v0, 4
            syscall
            # Print next line
            lb $a0, nextline
            li $v0, 4
            syscall

            j exitPrgm
        else:
            # Print No match
            lw $a0, str4
            li $v0, 4
            syscall


# Exit the program by means of syscall.

    exitPrgm:
    li $v0, 10 # Sets $v0 to "10" to select exit syscall
    syscall # Exit

# .data assembler directive
    .data

    inputArray:   .space 256
    constCharlwr: .byte  'e'
    result:       .byte  0
    NULL:         .byte  0
    i:            .byte  0

    str1:       .asciiz "Enter a word to search for letter e: \n"
    str2:       .asciiz "First match at address "
    str3:       .asciiz "The matching character is "
    str4:       .asciiz "No match found\n"
    nextline:   .asciiz "\n"   

person InfiniteParadigm    schedule 29.11.2019    source источник


Ответы (1)


Итак, я понял свою первоначальную проблему: я не использовал la для своих системных вызовов, и как только я это исправил, я начал получать желаемый результат. Единственная проблема сейчас в том, что я могу понять, как напечатать фактический адрес результата. Может кто-то помочь мне с этим. Новый код. Пытаюсь разными способами получить адрес памяти, но ничего не работает.

    # Prompt user for input
    la $a0, str1
    li $v0, 4
    syscall

    # Get user input and store in input array

    la $a0, inputArray
    li $a1, 255
    li $v0, 8
    syscall

    # set up registers
    lb $t0, i 
    lb $t1, NULL
    la $s2, inputArray
    lb $s3, result
    lb $t2, constCharlwr
    li $s0, 0
    add $s0, $s0, $s2  # s0 =  &arrayA[i]

    while:                           # while loop

        add $s0, $s0, $t0            # base address + 1 byte
        lb  $s1, 0($s0)              # load array index value into s1
        beq $s1, $t1, outsideWhile   # inputArray[i] != '\0'

        if1:
            bne  $s1, $t2, outsideIf # check if inputArray[i] == e 
            sb   $s1, result 
            j outsideWhile
        outsideIf:
        addi $t0, $t0, 1
        j while

    outsideWhile:

        if2:
            beq $s1, $t1, else
            # Print results
            # Print string 2
            la $a0, str2
            li $v0, 4
            syscall
            # Print address of result
            la $t9, result
            li $t8, 4 
            li $t0, 0 
            #for:
            #    bge $t0, $t8  outsideFor  
            #    add $t9, $t9, $t0
            #    lb $t7, 0($t9)  
            #    sb $t7, resultAddr
            #    la $a0, resultAddr
            #    li $v0, 4
            #    syscall

            #    addi $t0, $t0, 1
            #    j for
            #outsideFor:
            sb 0($t9)  resultAddr
            la $a0, resultAddr
            li $v0, 4
            syscall

            sb 1($t9)  resultAddr
            la $a0, resultAddr
            li $v0, 4
            syscall

            sb 2($t9)  resultAddr
            la $a0, resultAddr
            li $v0, 4
            syscall

            sb 3($t9)  resultAddr
            la $a0, resultAddr
            li $v0, 4
            syscall

            # Print next line
            la $a0, nextline
            li $v0, 4
            syscall
            # Print string 3
            la $a0, str3
            li $v0, 4
            syscall
            # Print result char value
            la $a0, result
            li $v0, 4
            syscall
            # Print next line
            la $a0, nextline
            li $v0, 4
            syscall

            j exitPrgm
        else:
            # Print No match
            la $a0, str4
            li $v0, 4
            syscall
person InfiniteParadigm    schedule 30.11.2019