Почему мне нужно будет конвертировать числа в этой сборочной игре - PullRequest
1 голос
/ 18 января 2020

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

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

Один из вопросов этой работы:

Почему необходимо преобразование числа и как - при использовании метода сетки - преобразование между ASCII H происходит из шестнадцатеричного в двоичное

Почему мне нужно будет выполнить преобразование?

код игры

.data #storing data
    startmsg: .asciiz "I am thinking of a random number between 1 and 100\n\n"
    guessmsg: .asciiz "Enter your guess\n"
    tooHigh: .asciiz "Your guess is too high.\n"
    tooLow: .asciiz "\n\nYour guess is too low.\n"
    wingame: .asciiz "You have guessed the number. Well done!\n\n"
.text #start of program

start:
    jal random
    add $t0, $zero, $a0 # store random number $a0 in $t0
    li $v0, 4         # print string
    la $a0, startmsg
    syscall

#######################################
# Main game loop for guessing
guessing:
    la $a0, guessmsg
    li $v0, 4 # print string guessmsg
    syscall




    li $v0, 5 #read int from user
    syscall
        move $t1, $v0 # store input in t1
        #addi $t2, $zero, 1 #t2 = 1 (guess min)
    beq $t0, $t1, win # if stored int = user input, user won
    addi $s0, $s0, -1 # guess used, subtract
    blt $t0, $t1, goLower # if stored int < user input, guess is too high

    # otherwise, guess is too low
    la $a0, tooLow
    li $v0, 4 # print string tooLow
        syscall

    # loop guessing
    j guessing

#######################################
# goLower: Procedure if the user guess too high
goLower:
    la $a0, tooHigh
    li $v0, 4 # print tooHigh
    syscall
    # loop back to get another guess
    j guessing

#######################################
# User won, print win and restart
win:
    la $a0, wingame
    li $v0, 4 #print string wingame
    syscall
    j start


#############################################
# LEAF PROCEDURE
# random: generate a rand number between 0 - 100
random: 
    li $v0, 42        # SERVICE 41 for a rand int
    #addi $a0, $zero, 0 # random number >= 0
    addi $a1, $zero, 100 #random number < 100
    #xor $a0, $a0, $a0  # Select random generator 0
    syscall            # Generate random int (returns in $a0)
    jr $ra

1 Ответ

0 голосов
/ 18 января 2020

Код, как сейчас, использует сервис read_int (код системного вызова 5), вызывая его с помощью

li $v0, 5 #read int from user
syscall

Теперь, если вам нужно прочитать символы ASCII, вы должны использовать сервис read_string ( код системного вызова 8), который будет хранить буфер чтения в $a0 и его длину в $a1.

li $v0, 8 # Note the only change is 8 instead of 5
syscall

Теперь для сравнения входного номера с номером в коде у вас есть два варианта :

  • Напишите свой код так, чтобы набор сгенерированных чисел был в формате ASCII, и сравните два значения ASCII.
  • Преобразование вводимого пользователем символа ASCII в десятичное и сравнение чисел.

Для первого вам нужно разделить число на цифры, добавить к ним 48 и объединить результаты в строку.

Для второго решения вам нужно выполнить итерацию буфер и вычесть 48 для каждого символа ASCII.

Это алгоритм для преобразования массива ASCII в целое число, но для его работы предполагается, что вы сохранили буфер в $s1, $t0 содержит 10, а $s2 содержит 0:

lp:
  lbu $t1, ($s1)       #load unsigned char from array into t1
  beq $t1, $0, FIN     #NULL terminator found
  blt $t1, 48, error   #check if char is not a digit (ascii<'0')
  bgt $t1, 57, error   #check if char is not a digit (ascii>'9')
  addi $t1, $t1, -48   #converts t1's ascii value to dec value
  mul $s2, $s2, $t0    #sum *= 10
  add $s2, $s2, $t1    #sum += array[s1]-'0'
  addi $s1, $s1, 1     #increment array address
  j lp                 #jump to start of loop
...