Отображение числа в двоичном виде путем сдвига

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

пользовательский ввод в $s0

Loop:

and $t0,$s0,2147483648  // anding it with this number because only its MSB is 1 all other bits are zero

sll $s0,$s0,1

move $a0,$t0

li $v0,1
syscall

beq $t1,31,Exit

addi $t1,$t1,1
j Loop

ОБНОВЛЕНИЕ: я изменил этот код в соответствии с предложением dbrank0, но теперь он отображает только один бит вместо 32 бит

Loop:

and $t0,$s0,2147483648

sll $s0,$s0,1

beq $t1,31,Exit

move $a0,$t0

addi $t1,$t1,1

bgtu $t0,0,Check

li $t0,0
j Loop

Disp:
li $v0,1
syscall

j Loop

Check:
li $t0,1

j Disp

Будет много, если кто-нибудь поможет мне решить эту проблему.

С уважением

2 ответа

Решение

Вот проблема:

bgtu  $t0, 0, Check
li    $t0, 0
j     Loop

Если это ноль, он не отображается, потому что вы переходите к Loop вместо Disp, О, посмотри, Disp в любом случае написано сразу после этой инструкции! Решение: избавиться от прыжка в целом.

Вот еще одна проблема, как описано в dbrank0:

Disp:
li $v0,1
syscall

Это будет отображать содержимое $a0 как целое число Но если бит был 1, значение $a0 будет 0x80000000, а не 1! Когда вы попытаетесь напечатать 0x80000000, он будет обрабатывать его как целое число со знаком и вместо этого выдает -2147483648.

Вот еще одна проблема:

beq $t1,31,Exit

Во-первых, эта инструкция находится в неловком месте. Почему вы проверяете состояние выхода после and а также shift? Вы должны проверить это либо в начале, либо в конце, а не в середине. Кроме того, вам нужно сравнить с 32, потому что есть 32 бита, и вы проверяете перед печатью каждого бита. В настоящее время последний бит будет отрублен в результате.


Есть умный способ заставить вашу программу выполнять меньше работы, чем нужно. Воспользуйтесь тем, что вы отображаете слева направо (т. Е. Самый старший бит отображается первым). Когда MSB установлен, его можно рассматривать как отрицательное число в дополнении к двум!

li     $t0, 32
li     $v0, 1

Loop:
bltz   $s0, Bit1
li     $a0, 0
j      Disp

Bit1:
li     $a0, 1

Disp:
syscall

Tail:
subi   $t0, $t0, 1
beqz   $t0, Exit
sll    $s0, $s0, 1
j      Loop

Exit:

Дан указатель на конец достаточно большого буфера в $a1и входное целое число в $a0эта функция сохраняет ASCII-цифры для формирования строки.

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

.globl to_base2_end    # args: (unsigned a, char *buf_end)
to_base2_end:

  # Runs at least once, so we get "0" instead of the empty string for 0
.loop:                           # do {
    andi  $t0,  $a0, 1           #    extract the low bit
    ori   $t0,  $t0, '0'         #    ASCII digit

    addiu $a1,  $a1, -1
    sb    $t0,  ($a1)            #    *--buf = ASCII digit

    srl   $a0,  $a0, 1           #    a0 >>= 1
    bne   $a0, $zero,  .loop     # }while (a0!=0);

    move  $v0, $a1           # return pointer to the first digit
    jr   $ra

Обратите внимание, что это уменьшается до первого хранилища, так что вы можете передать ему указатель на '\n' в конце буфера.

Конечно, вы можете встроить этот цикл вместо использования его в качестве вызываемой функции. Он останавливается, когда целое число равно нулю, вместо зацикливания фиксированных 32 раз, поэтому он не выводит начальные нули.

Этот алгоритм является частным случаем base2 основного
do { digit = a % base; } while(a /= base);,

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

    slt   $t0,  $a0, $zero       #    t0 = 0 or 1 = high bit of a0
    sll   $a0,  $a0, 1

Это даст вам версию кода @JeffE без ответвлений. Но если вы заботитесь об эффективности, один системный вызов, который записывает целую строку, гораздо эффективнее, чем 32 системных вызова, чтобы записать 32 целых числа. (И, конечно, реальные ОС не имеют системных вызовов write-int; это вещь Mars/SPIM.)

Другие вопросы по тегам