Как правильно использовать указатель в MIPS? - PullRequest
1 голос
/ 01 августа 2020

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

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

Код выглядит следующим образом:

.data
first: .word 5, 6, -128, -5, 260, 34, 3, 20, -1
last: .word 44

max: .space 4  


.text
lw $t0, first
lw $t1, last
lw $t5, max


sw $t5, $t0
loop: 

beq $t0, $t1, ex
addi $t0, $t0, 4
bgt $t0, $t5, swapmax
j loop


swapmax: 
lw $t0, ($t5)

ex: 
lw $t5, max
li $v0, 10
syscall

Где мне нужны скобки и почему?

Программа компилируется, но я получаю ошибка:

попытка выполнить не-инструкцию по адресу 0x800000180

Что означает эта ошибка?

Ответы [ 2 ]

2 голосов
/ 01 августа 2020

Что означает эта ошибка?

0x800000180 - это адрес обработчика исключений ядра.

Это происходит, потому что ваш код получает исключение.

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

Чтобы увидеть, какая инструкция в вашем коде запускает двойное исключение, один шаг ваш код, пока он не перейдет в 0x800000180, и go назад на одну инструкцию от этого. Почти наверняка это будет инструкция загрузки или сохранения, для которой был задан неверный указатель адреса памяти.

Кроме того, следует прислушаться к предложениям @Wagar.

1 голос
/ 01 августа 2020

Что такое указатели?

Указатели - это то, что указывает на область памяти. Мы используем указатели для размещения значений в ячейках памяти. Например, в C:

int max;
int *ptr = &max;
*ptr = 22; // max = 22

В приведенном выше примере ptr указывает на ячейку памяти (max), и мы изменяем значение max на ptr путем разыменования.

Как их правильно использовать в MIPS?

Чтобы понять это, вам нужно понимать синтаксис инструкции и какие операнды принимает каждая инструкция. Очевидно, мы не можем go выполнить все инструкции в одном ответе, поэтому я просто покажу вам несколько, чтобы вы поняли:

lw register, memory_location
sw register, memory_location
la register, memory_location 
  • lw загружает слово из памяти в регистр . Примеры:
lw $t0, first
lw $t0, ($t5) # this is like, int t0 = *t5
  • sw сохраняет значение из регистра в ячейку памяти . Пример:
sw $t0, max # max = t1
sw $t0, ($t5) # *t5 = t0
  • la загрузит адрес ячейки памяти в регистр.
la $t5, max # int *t5 = &max

Давайте теперь посмотрим на ошибки в вашем коде. Здесь:

lw $t5, max   

Выше будет загружено значение max в $t5. Похоже, вы создали max для хранения максимального значения. Загружать его здесь кажется бессмысленным, потому что он даже ничего не содержит. Вы хотите загрузить его адрес, используя la:

la $t5, max #load address of max variable into $t5

Двигаясь дальше, мы видим эту инструкцию:

sw $t5, $t0

Это не будет собираться. Это приведет к ошибке. sw имеет первый операнд (источник) как регистр, а второй операнд - это «ячейка памяти», а не регистр.

sw register, memory_location

Итак, если вы хотите что-то сохранить, вы должны:

sw $t5, ($t0)       #store value inside $t5 at the 'address' inside $t0.

# Assume:
# $t5 = 23
# $t0 = 0x5555
# After executing this instruction, memory location 0x5555 would have value 23 in it

Это было просто объяснение. В приведенном выше коде вы присвоили $t0 = first. Это даже не указывает на ячейку памяти! Однако $ t5 будет иметь ячейку памяти, если вы сделаете la $t5, max.

Итак, я предполагаю, что вы хотели сделать:

sw $t0, ($t5)
# After executing this, 'max' == $t0 because $t5 is pointing at max.

Двигаясь дальше, мы видим:

bgt $t0, $t5, swapmax

Как вы уже догадались, это неверно. Причина: вы сравниваете «адрес» со значением. «Адрес» находится в $ t5, «Значение» - в $ t0. Если вы хотите получить значение внутри $ t5, вам нужно сначала загрузить его. Возможно, используя другой регистр:

lw $t3, ($t5)
#OR
lw $t3, max   # same thing, $t5 is pointing at 'max'

Это очевидные ошибки. Возможны логические ошибки, но это ваш код и ваша программа, поэтому я оставлю вам изменять ваш лог c по мере необходимости

...