Как мне получить доступ к .word data ‘source’, увеличить до каждого номера, назначить ‘destination’?

#assembly #mips #mars-simulator

#сборка #mips #марс-симулятор

Вопрос:

Пытаюсь получить доступ и перебирать каждое число в «источнике», пока не наберу 0, затем сохраняю эти числа в том же индексе «назначения».

Пробовал: много чего, не удалось получить доступ к .данные word правильно. не уверен, почему..

 .data
source:     .word   3, 1, 4, 1, 5, 9, 0
dest:       .word   0, 0, 0, 0, 0, 0, 0
countmsg:   .asciiz " values copied. "

.text

main:   add $s0,    $0,     $ra # Save our return address
    la  $t0,    source
    la  $t1,    dest


loop:   lw  $t3,    ($t0)       # read next word from source
    beq $t3,    $zero,  loopend # loopend if word is 0
    addi    $t4,    $t4,1       # increment count words copied
    sw  $t3,    0($t1)      # write to destination
    addi    $t0,    $t0,1       # advance pointer to next source
    addi    $t1,    $t1,1       # advance pointer to next dest
    j loop
loopend:

    move    $a0,    $v0     # We want to print the count
    li  $v0,    1
    syscall             # Print it
    la  $a0,    countmsg    # We want to print the count msg
    li  $v0,    4
    syscall             # Print it
    li  $a0,    0x0A        # We want to print 'n'
    li  $v0,    11
    syscall             # Print it
    jr  $s0         # Return from main. $ra in $s0
 

не выровнен по границе слова, не уверен, как выстроить итерацию

Ответ №1:

Проблема заключается в том, как вы увеличиваете указатели на массив. word имеет ширину 4 байта, и для доступа к следующему элементу требуется добавить 4 к адресу. Это определенно объясняет, почему у вас не выровненные обращения.

Есть пара других проблем.

main это специальная функция, и вы не должны возвращаться из main, а вызывать exit() ( syscall 10 )

И количество слов $t4 введено и напечатано неправильно.

Я также изменил ваш цикл, чтобы в нем была уникальная ветвь и чтобы подавить окончательный переход. Всегда лучше выполнять тест в конце цикла способом do-while.

Вот исправленная версия:

 .data
source:     .word   3, 1, 4, 1, 5, 9, 0
dest:       .word   0, 0, 0, 0, 0, 0, 0
countmsg:   .asciiz " values copied. "

.text

main:   ### main is a special function. Should not save $ra
            #### $ra add $s0,    $0,     $ra # Save our return address
    la  $t0,    source
    la  $t1,    dest

loop:    lw  $t3,    ($t0)   # read next word from source
    addi $t4,    $t4,1       # increment count words copied
    sw   $t3,    0($t1)      # write to destination
    addi $t0,    $t0,4       # advance pointer to next source
        ### increment must be sizeof(word), ie 4
    addi $t1,    $t1,4       # advance pointer to next dest
    bne  $t3,$zero, loopend # loopend while word is != 0
        ### no longer required    j loop
loopend:

    move $a0,    $t4    # We want to print the count
                            # which is in $t4    
    li  $v0,    1
    syscall             # Print it
    la  $a0,    countmsg    # We want to print the count msg
    li  $v0,    4
    syscall             # Print it
    li  $a0,    0x0A        # We want to print 'n'
    li  $v0,    11
    syscall             # Print it
    li  $a0,    0       # EXIT_SUCCESS
    li  $v0,    10
    syscall             # exit
##    jr  $s0         # NO Return from main. use exit syscall