Сборка MIPS: функция INT to STRING только 2 символа (обрезать последний символ)

Я написал эту функцию для преобразования значения int в строку ascii. Но когда вводится что-то вроде 315, в строку будет напечатано 31. Поскольку я не эксперт в сборке, любая помощь в этом будет оценена. Вот код: (int_buf — это место, где хранится целочисленный ввод, $a — строковый вывод)

 itoa:
  la      $t0, int_buf   # load buf
  add     $t0, $t0, 30   # seek the end
  sb      $0, 1($t0)     # null-terminated str
  li      $t1, '0'  
  sb      $t1, ($t0)     # init. with ascii 0
  li      $t3, 10        # preload 10
  beq     $t8, $0, iend  # end if 0
loop:
  div     $t8, $t3       # a /= 10
  mflo    $t8
  mfhi    $t4            # get remainder
  add     $t4, $t4, $t1  # convert to ASCII digit
  sb      $t4, ($t0)     # store it
  sub     $t0, $t0, 1    # dec. buf ptr
  bne     $t8, $0, loop  # if not zero, loop
  addi    $t0, $t0, 1    # adjust buf ptr
iend:
  move    $a1, $t0       # return the addr.
  jr      $ra            # of the string

РЕДАКТИРОВАТЬ: я обнаружил, что проблема не в функции, а в том, как я потом печатаю строку в файл:

li    $v0, 15
move  $a0, $s6      
move  $t8, $s2
jal   itoa
li    $a2, 4 //problem was only 2 digits selected here!
syscall

Как я могу запретить инструменту печатать пустые символы в моем файле, если я установил по умолчанию 4 цифры?


person pike93    schedule 19.01.2016    source источник
comment
Похоже, $t8 — целочисленный ввод, $a1 — адрес выходной строки ASCII. У вас есть отладчик, в котором вы можете выполнить этот код пошагово?   -  person amdn    schedule 19.01.2016
comment
Да, когда в 'mflo $t8' $t8 имеет значение 27, что является значением int, заданным для функции в этом случае.   -  person pike93    schedule 19.01.2016
comment
Если введено 27 (десятичное число), то в mflo (Move From LO, частное после деления на 10, которое находится в $t3) регистр $t8 по-прежнему будет 27... первая инструкция шага (mflo) и регистр $t8 должно содержать частное (2 десятичных знака).   -  person amdn    schedule 19.01.2016
comment
когда вводится что-то вроде 315, в строке будет напечатано 31 Я не могу воспроизвести это с помощью PCSpim. Если я ввожу 315, я получаю 315 на выходе. Пожалуйста, опубликуйте полный минимальный пример, который можно использовать для воспроизведения проблемы.   -  person Michael    schedule 19.01.2016
comment
Когда функция возвращает, и $a1, и $t0 будут иметь адрес строки в памяти. Если введено десятичное число 315, вы должны увидеть 0x33 0x31 0x35 0x00 в последовательных байтах в памяти по адресу в $t0. Они соответствуют значениям ASCII для «3», «1», «5» и завершающему нулю.   -  person amdn    schedule 19.01.2016
comment
Проблема не в функции, как сказал Майкл. Спасибо вам обоим за помощь :)   -  person pike93    schedule 19.01.2016
comment
Без проблем. Если системному вызову требуется количество байтов в $a2, то вам не следует жестко кодировать его равным 4. Два варианта: (1) изменить функцию itoa, чтобы она поместила длину в $a2, или (2) вычислить длину после того, как itoa вернет .   -  person amdn    schedule 19.01.2016
comment
Да, но в этом суть. Как я могу получить длину целочисленного значения?   -  person pike93    schedule 19.01.2016
comment
Что ж, в функции itoa вы знаете, что $t0 указывает на первый допустимый символ (байт) строки, и вы знаете, что строка выровнена по правому краю в 32-байтовом буфере, int_buf. Таким образом, длина строки составляет int_buf + 32 - $t0 (включая нулевой терминатор).   -  person amdn    schedule 19.01.2016


Ответы (1)


Как я могу запретить инструменту печатать пустые символы в моем файле, если я установил по умолчанию 4 цифры?

Подсчитать количество цифр в строке несложно. Вы знаете, что символы NUL-терминатора находятся в int_buf+31 из-за того, как пишется itoa. Так что просто возьмите разницу между этим и адресом, который вы получите от itoa:

li $a2,int_buf+31
sub $a2,$a2,$a1  # a2 is now equal to the number of digits in the string
person Michael    schedule 19.01.2016
comment
Вы можете попробовать использовать la вместо li. В любом случае, он отлично работает с li в PCSpim. - person Michael; 19.01.2016
comment
Вероятно, поэтому itoa сделала это в два шага (ограничение ассемблера?)... la $t0, int_buf # загрузить buf add $t0, $t0, 31 # указать на нулевой байт - person amdn; 19.01.2016
comment
@amdn должен ли я тогда использовать $t0 в li? - person pike93; 19.01.2016
comment
Регистр, который вы используете, не должен иметь значения, за исключением того, что у вас есть один из операндов в $a1 (адрес, возвращаемый itoa), и вы, вероятно, хотите получить результат в $a2. Поэтому мне кажется проще всего использовать эти два регистра для этого расчета. - person Michael; 19.01.2016
comment
@ pike93, извините за путаницу, как сказал Майкл, вы можете просто использовать $a2 - person amdn; 19.01.2016
comment
Проблема в том, что я не могу использовать переменную в li, потому что тогда QtSpim выдает мне синтаксическую ошибку. - person pike93; 19.01.2016