2017-02-02 2 views
0

Я читал многочисленные темы здесь и в других местах в Интернете по этой теме. Отличные темы о смещениях бит (не обязательно относящиеся к сборке, но тема в целом: What are bitwise shift (bit-shift) operators and how do they work? Я дошел до копирования и вставки кода из OP здесь: How do I print a binary number with an inputed integer? и внесения изменений, которые предлагал репитер, и продолжаю создайте строку нуля независимо от того, что я делаю.MIPS Использование операторов битового сдвига для печати десятичного разряда в двоичном формате

Я понимаю, что такое сдвиг бит и как оно работает. Сдвиг вправо на «n» делит число на 2^n, а сдвиг влево умножает число на 2^n.

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

Мои первоначальные мысли заключались в том, чтобы взять строку, а она с 0x01, напечатать результирующие «1» или «0», а затем сдвинуть бит справа на «1». Это содержалось в цикле и продолжалось до тех пор, пока мой счетчик не выполнил требование «32» и не выполнил его. Но я очень смущен, почему он печатает все «0». Я попробовал другие варианты, такие как:

  • сдвига пользовательского ввода влево на 31, а затем сделать петлю для каждого бита, но внутри цикла он смещается вправо (чтобы на обратном порядке бит) - не удался - все нули снова

  • делать противоположную сверху - не удались еще раз, все нули

Я знаю, что в моей голове, что я хочу сделать, это что-то вроде этого:

(NOT CODE OBVIOUSLY) 
User input is: 25 <-- store at $t0 
    Binary rep is: 0000 0000 0000 0000 0000 0000 0001 1001 # 25 in $t0 

LOOP: 
    AND with 0x01: 0000 0000 0000 0000 0000 0000 0000 0001 #saved to $t1 

    Produces:  0000 0000 0000 0000 0000 0000 0000 0001 #saved to $t2 

    Print to Console: 1 #send contents of $t2 to syscall 

    Shift $t0 Right 1: 0000 0000 0000 0000 0000 0000 0000 1100 # 

j LOOP (until the beq branch was met and I left the loop) 

Я бы подумал, что это сработало бы. Даже если бы это привело к обратному результату, я подумал, что я все равно получил бы «1 в моей выпущенной строке, которую я бы заметил и обработал соответственно» (сдвиньте весь номер, оставшийся в $t0, на «31», а затем выполнили приведенные выше инструкции. все '0's ...

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

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

#Read integer A from user and store it into a register 
#Display the integer in binary 
#Display the integer in Hex 
#set Register $a0 to contain only bits 12,13,14,15 of $a0 
#Display the integer in binary contained in $a0 
#Display the integer in hex contained in $a0 

.data 

    userInput: .asciiz "Please enter your integer:\n" 
    binaryInput: .asciiz "Here is the input in binary: " 
    nl: .asciiz "\n\n" 
    hexInput: .asciiz "Here is the input in hexidecmal: " 
    binaryOutput: .asciiz "Here is the output in binary: " 
    hexOutput: .asciiz "Here is the output in hexidecimal: " 

.text 
    main: 

    #ask end-user to submit an integer value 
    li $v0, 4 
    la $a0, userInput 
    syscall 

    #read user-input 
    li $v0, 5 
    syscall 

    #enter user input into $t0 
    move $t0, $v0 
    add $t1, $zero, $zero  #counter 
    addi $t2, $zero, 32  #target 
    sll $s1, $t0, 31  #shift left number 31 bits to s1 
    li $v0, 4 
    la $a0, binaryInput  #print out string to user 
    syscall 


loop: 
    andi $s2, $s1, 1  #and 0x01 with s1 to s2 
    srl $s1, $s1, 1   #shift right s1 by 1 bit 
    li $v0, 1 
    la $a0, ($s2)   #print digit held in s2 to screen 
    syscall 
    add $t1, $t1, 1   #add 1 to counter 
    bne $t1, $t2, loop  #check if counter is equal to target, if not continue loop 

    #exit the program 
    li $v0, 10 
    syscall 
+0

Утверждение, что пользовательский ввод равен 25 - было ли это введено как входное и входящее как строка, или оно передавалось как фактическое значение вашей функции? Если он передан как строка, вам сначала нужно сделать некоторые преобразования, чтобы получить его от строки до целого. Затем, нужна ли функции печати строка или число? Я предполагаю строку, и в этом случае вам нужно добавить '0' к вашему двоичному значению, чтобы он печатался правильно. –

+2

'la $ a0, ($ s2)' действительно странно. 'la' должен быть как' li', но с 0x1001 как верхняя половина числа. Я удивляюсь, что это даже собрано, и нужно задаться вопросом, в чем он собрался. – harold

+0

@MichaelDorgan Hmmm большие вопросы! Целое число - это пользовательский ввод, который я читаю как «li $ v0, 5' в моем коде. В строке 3 моей «петли» я печатаю целочисленное значение. Я думал, это сработало бы? – Pwrcdr87

ответ

2

Это метод, который несколько отличается от вашего базового подхода. Он обрабатывает двоичный выход и шестнадцатеричный вывод в качестве параметров для общей выходной функции. Маскировка бит/смещение бит аналогична, но маска и ширина бита являются переменными.

# Read integer A from user and store it into a register 
# Display the integer in binary 
# Display the integer in Hex 
# set Register $a0 to contain only bits 12,13,14,15 of $a0 
# Display the integer in binary contained in $a0 
# Display the integer in hex contained in $a0 

    .data 
userInput: .asciiz  "Please enter your integer: " 
binaryInput: .asciiz "Here is the input in binary: " 
nl:   .asciiz  "\n" 
hexInput: .asciiz  "Here is the input in hexadecimal: " 
binaryOutput: .asciiz "Here is the output in binary: " 
hexOutput: .asciiz  "Here is the output in hexadecimal: " 
hexDigit: .asciiz  "ABCDEF" 
obuf:  .space  100 
obufe: 

    .text 
    .globl main 
main: 
    # ask end-user to submit an integer value 
    li  $v0,4 
    la  $a0,userInput 
    syscall 

    # read user-input 
    li  $v0,5 
    syscall 
    move $s0,$v0 

    # output original in binary 
    la  $a0,binaryInput 
    li  $a1,32 
    jal  prtbin 

    # output original in hex 
    la  $a0,hexInput 
    li  $a1,32 
    jal  prthex 

    # isolate bits 12,13,14,15 
    srl  $s0,$s0,12 
    andi $s0,$s0,0x0F 

    # output isolated in binary 
    la  $a0,binaryOutput 
    li  $a1,4 
    jal  prtbin 

    # output isolated in hex 
    la  $a0,hexOutput 
    li  $a1,4 
    jal  prthex 

    # exit the program 
    li  $v0,10 
    syscall 

# prtbin -- print in binary 
# 
# arguments: 
# a0 -- output string 
# a1 -- number of bits to output 
prtbin: 
    li  $a2,1     # bit width of number base digit 
    j  prtany 

# prthex -- print in binary 
# 
# arguments: 
# a0 -- output string 
# a1 -- number of bits to output 
prthex: 
    li  $a2,4     # bit width of number base digit 
    j  prtany 

# prtany -- print in given number base 
# 
# arguments: 
# a0 -- output string 
# a1 -- number of bits to output 
# a2 -- bit width of number base digit 
# s0 -- number to print 
# 
# registers: 
# t0 -- current digit value 
# t5 -- current remaining number value 
# t6 -- output pointer 
# t7 -- mask for digit 
prtany: 
    li  $t7,1 
    sllv $t7,$t7,$a2    # get mask + 1 
    subu $t7,$t7,1    # get mask for digit 

    la  $t6,obufe    # point one past end of buffer 
    subu $t6,$t6,1    # point to last char in buffer 
    sb  $zero,0($t6)   # store string EOS 

    move $t5,$s0     # get number 

prtany_loop: 
    and  $t0,$t5,$t7    # isolate digit 
    lb  $t0,hexDigit($t0)  # get ascii digit 

    subu $t6,$t6,1    # move output pointer one left 
    sb  $t0,0($t6)    # store into output buffer 

    srlv $t5,$t5,$a2    # slide next number digit into lower bits 
    sub  $a1,$a1,$a2    # bump down remaining bit count 
    bgtz $a1,prtany_loop   # more to do? if yes, loop 

    # output string 
    li  $v0,4 
    syscall 

    # output the number 
    move $a0,$t6     # point to ascii digit string start 
    syscall 

    # output newline 
    la  $a0,nl 
    syscall 

    jr  $ra      # return 
+0

Спасибо Крэйг Эсте! Я запустил это несколько раз и, похоже, работает отлично. Мне нужно проанализировать ваш код, когда я получаю возможность, так как мы только что узнали о прыжках, которые вы делаете всего лишь день назад, а также о том, как передавать аргументы, как вы это делаете. 'subu' тоже для меня тоже. Но это отличный крутой курс по этим темам для меня. – Pwrcdr87

+0

harold, я бы дал вам больше очков за помощь, которую вы мне дали изначально. К сожалению, все, что я мог сделать, это повысить ваши ответы на мой первоначальный пост. Извините, но я очень благодарен вам за то, что вы нашли время, чтобы посмотреть мой начальный код и указать на определенные области, где я ошибался. – Pwrcdr87

Смежные вопросы