Как сохранить значения ascii в массиве с помощью mips?

#arrays #assembly #mips

#массивы #сборка #mips

Вопрос:

Я пишу функцию, которая принимает три аргумента. $a0 является положительным int значением и $a1 является массивом и $a3 размером массива. Я должен принять первый аргумент и преобразовать его в десятичную цифру ascii. затем сохраните эту цифру в массиве. Я продолжаю делать это, пока не останется больше цифр для преобразования. Я должен вернуть последний адрес массива и последнее значение ascii, которое я сохраняю (которое я помещаю в $v0 и $v1 ). Что я делаю не так?

uitoa:

 li $t0 , 0   
li $t1 , 10
li $t4 , 48
li $t8 , 0
for :
beq $a0,$t8,finished
div $a0,$t1
mfhi $t2 #remainder
mflo $a0
add $t3,$t2,$t4 #  48 to ascii
add $t6 , $t6 , $a1  #address of array?
sb $t3, 0($t6)
addi $t6,$t6,1 # increment array ?
addi $t0, $t0 ,1
j for

finished:

la $v0 , ($t6)
la $v1 , ($t3)
  

Комментарии:

1. Что происходит не так?

2. в нем говорится, что адрес находится вне диапазона для sb $ t3,0 ($ t6)

Ответ №1:

add $t6 , $t6 , $a1 есть t6 = t6 a1 , но это первый раз, когда вы используете t6 , поэтому его значение не определено (что, к счастью, приводит к «выходу за пределы диапазона» при попытке записать туда байт, если он случайно закончится в какой-либо записываемой памяти, вы просто получите неверный результат плюс некоторая случайная перезапись памяти, вызывающаяочень вероятно, что все виды странного поведения в других местах).

Также вы будете делать это add каждый цикл в цикле (добавляя a1 адрес к ранее установленному t6 ), поэтому во втором цикле вы будете отключаться, даже если вы заранее установите t6 значение ноль.

Для нулевого ввода вы просто переходите к finished , но вы не сохраняете один '0' символ в массив, и ни t6 t3 один из них не инициализируется (но используется).

По завершении la v1,(t3) будет считываться память? Я думаю, вы намеревались просто скопировать t3 в v1 ? Поэтому используйте загрузку из регистра (не уверен в мнемонике mips, я никогда не изучал mips asm).

Вы используете t0 напрасно.

И, деля число на 10 в цикле, вы получаете цифры в обратном порядке, но похоже, что массив заполняется постепенно.

В целом похоже, что вы поняли, что вам следует делать, но сразу начали выдавать инструкции. Остановитесь на некоторое время и разделите свой алгоритм на несколько простых шагов, записанных в коде в виде комментариев к целой строке, затем перейдите к ним для различных сложных входных данных (0, 1, 10, max_positive_int) и убедитесь, что логика в порядке (программирование резиновой утки). Делайте дополнительные заметки под шагами, какие значения им нужны, постарайтесь упростить это, делайте заметки, где они должны быть инициализированы, и назначайте им регистры.

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

Кстати, из вашего вопроса похоже, что вы не удосужились запустить его в отладчике ни разу. Программирование на ассемблере работает не так, особенно если вы только учитесь. Это также дает вам право на понижение ответа на вопрос (недостаточно усилий, прежде чем задавать вопрос), хотя мне все равно, я бы предпочел понизить голос людей, не прилагающих усилий для понимания ответов .. : D

Комментарии:

1. Мне как бы интересно, как справиться с обратной записью массива, не могу придумать ничего действительно элегантного, так как вы не можете заранее сказать, сколько символов будет сохранено, поэтому либо запишите его в обратном направлении и переверните его в конце, либо запишите его с конца (a1 a3-1), а затемпереместить содержимое в сторону a1 0? Другой вариант — сохранить вычисленные цифры в стек посчитать их и после достижения нуля извлекать их из стека по одному и заполнять массив с самого начала (плюс я не уверен, какое тогда правильное значение для возвращаемых значений v0 / v1, должно ли оно ссылаться на самую правую цифру строки,вероятно).