Как правильно читать целочисленный ввод в MIPS?

Следующая программа
1. Распечатывает массив
2. Учитывая введенные пользователем нижнюю и верхнюю границы, определяет минимальный и минимальный индекс в этом диапазоне

Он запускает функцию печати массива.

Однако я попытался отследить регистры в QTSPIM, он неправильно присваивает нижнюю и верхнюю границы $a0 и $a1 соответственно. На самом деле $v0 ​​даже ничего не сканирует. Чтобы переместить отсканированный ввод из $v0 в $t0, попробуйте вместо этого использовать «переместить $t0, $v0». Проблема все еще возникает.

# Ask the user for two indices
    li   $v0, 5             # System call code for read_int
    syscall 
    add  $t0, $v0, $zero    # store input in $t0          
    sll  $t0, $t0, 2    # relative address position (lower bound)
    add  $a0, $t9, $t0      # array pointer (lower bound) 

    li   $v0, 5             # System call code for read_int
    syscall           
    add  $t0, $v0, $zero    # store input in $t0          
    sll  $t0, $t0, 2    # relative address position (upper bound) 
    add  $a1, $t9, $t0      # array pointer (upper bound) 

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

# arrayFunction.asm
       .data 
array: .word 8, 2, 1, 6, 9, 7, 3, 5, 0, 4
newl:  .asciiz "\n"

       .text
main:
    # Print the original content of array
    # setup the parameter(s)
    la $a0, array            # base address of array
    add $t9, $a0, $zero      # store base address
    la $a1, 10       # number of elements in array
    # call the printArray function
    jal printArray           # call function 


    # Ask the user for two indices
    li   $v0, 5             # System call code for read_int
    syscall 
    add  $t0, $v0, $zero    # store input in $t0          
    sll  $t0, $t0, 2    # relative address position (lower bound)
    add  $a0, $t9, $t0      # array pointer (lower bound) 

    li   $v0, 5             # System call code for read_int
    syscall           
    add  $t0, $v0, $zero    # store input in $t0          
    sll  $t0, $t0, 2    # relative address position (upper bound) 
    add  $a1, $t9, $t0      # array pointer (upper bound) 

    # Call the findMin function
    # setup the parameter(s)    
    # call the function
    jal findMin     # call function 


    # Print the min item
    # place the min item in $t3 for printing
    addi $t3, $t1, 0 
    # Print an integer followed by a newline
    li   $v0, 1         # system call code for print_int
        addi $a0, $t3, 0        # print $t3
        syscall             # make system call

    li   $v0, 4         # system call code for print_string
        la   $a0, newl      
        syscall             # print newline

    #Calculate and print the index of min item
    la  $a0, array
    add $t3, $v0, $a0
    srl $t3, $t3, 2 

    # Place the min index in $t3 for printing   

    # Print the min index
    # Print an integer followed by a newline
    li   $v0, 1         # system call code for print_int
        addi $a0, $t3, 0        # print $t3
        syscall             # make system call

    li   $v0, 4         # system call code for print_string
    la   $a0, newl      # 
    syscall             # print newline

    # End of main, make a syscall to "exit"
    li   $v0, 10        # system call code for exit
    syscall             # terminate program


#######################################################################
###   Function printArray   ### 
#Input: Array Address in $a0, Number of elements in $a1
#Output: None
#Purpose: Print array elements
#Registers used: $t0, $t1, $t2, $t3
#Assumption: Array element is word size (4-byte)
printArray:
    addi $t1, $a0, 0    #$t1 is the pointer to the item
    sll  $t2, $a1, 2    #$t2 is the offset beyond the last item
    add  $t2, $a0, $t2  #$t2 is pointing beyond the last item
l1: 
    beq  $t1, $t2, e1
    lw   $t3, 0($t1)    #$t3 is the current item
    li   $v0, 1         # system call code for print_int
        addi $a0, $t3, 0        # integer to print
        syscall             # print it
    addi $t1, $t1, 4
    j l1            # Another iteration
e1:
    li   $v0, 4         # system call code for print_string
        la   $a0, newl      # 
        syscall             # print newline
    jr $ra          # return from this function


#######################################################################
###   Student Function findMin   ### 
#Input: Lower Array Pointer in $a0, Higher Array Pointer in $a1
#Output: $v0 contains the address of min item 
#Purpose: Find and return the minimum item 
#              between $a0 and $a1 (inclusive)
#Registers used: $t0 (counter), $t1 (max add), $t2 (min), $v0 (min pos), $t3 (current item)
#Assumption: Array element is word size (4-byte), $a0 <= $a1
findMin:


    lw, $t2, 0($a0)         # initialise min (value) to the lower bound  
    addi $t0, $a0, 0    # initialise $t0 (current pointer) to lower bound 
    addi $t1, $a1, 0    # initialise $t1 (add of end of array) to upper bound 
Loop:   slt $t4, $t1, $t0
    bne $t4, $zero, End     # branch to end if upper < lower

    lw, $t3, 0($a0)     # store the content of the lower array pointer
    slt $t4, $t3, $t2   # if current ($t3) < min ($t2), store 1 in $t4
    beq $t4, $zero, LoopEnd # if it is 0, go to LoopEnd

    addi $t2, $t3, 0    # store content ($t3) as minimum ($t2)
    addi $v0, $t0, 0        # store the address of min

LoopEnd: addi, $t0, 4       # increments current pointer lower bound 
     j Loop         # Jump to loop 
End:    
    jr $ra          # return from this function


person goldilocks    schedule 28.02.2020    source источник
comment
Если вы спрашиваете, как читать целое число в MIPS, у вас слишком много кода. Предложите вам сосредоточиться, сосредоточиться, сосредоточиться на том, с чем у вас действительно проблемы, в этом формате вопросов и ответов.   -  person Erik Eidt    schedule 28.02.2020
comment
да, проблема возникает в первом фрагменте кода. Остальные просто дополнительные.   -  person goldilocks    schedule 28.02.2020
comment
@goldilocks: код для чтения целого числа выглядит нормально. У вас есть синтаксическая ошибка в строке LoopEnd: addi, $t0, 4. Я думаю, вы, вероятно, имели в виду LoopEnd: addi $t0, $t0, 4   -  person gusbro    schedule 28.02.2020


Ответы (1)


Вы правильно читаете целые числа. Проблемы в другом

  • В функции findMin вы используете lw, $t3, 0($a0), но вы должны использовать ее с $t0 вместо $a0.
  • После того, как вы вернетесь из этой функции, вы случайно сохраните $t1 как минимальное значение, а не $t2, которое фактически содержит его.
  • Также вы не сохраняете $v0, который содержит указатель на минимальное значение, поэтому позже вы используете некоторые мусорные данные, а не предполагаемые.
  • Когда вы вычисляете индекс min из указателя, вы используете add, но он должен быть sub.
  • Также, как было упомянуто в комментариях на LoopEnd, добавление синтаксически неверно. Должно быть addi $t0, $t0, 4. Но это может быть просто ошибка копирования.

Вот фиксированный код. Изменена строка с пометкой ERROR.

# arrayFunction.asm
       .data 
array: .word 8, 2, 1, 6, 9, 7, 3, 5, 0, 4
newl:  .asciiz "\n"

       .text
main:
    # Print the original content of array
    # setup the parameter(s)
    la $a0, array            # base address of array
    add $t9, $a0, $zero      # store base address
    la $a1, 10       # number of elements in array
    # call the printArray function
    jal printArray           # call function 


    # Ask the user for two indices
    li   $v0, 5             # System call code for read_int
    syscall 
    add  $t0, $v0, $zero    # store input in $t0          
    sll  $t0, $t0, 2    # relative address position (lower bound)
    add  $a0, $t9, $t0      # array pointer (lower bound) 

    li   $v0, 5             # System call code for read_int
    syscall           
    add  $t0, $v0, $zero    # store input in $t0          
    sll  $t0, $t0, 2    # relative address position (upper bound) 
    add  $a1, $t9, $t0      # array pointer (upper bound) 

    # Call the findMin function
    # setup the parameter(s)    
    # call the function
    jal findMin     # call function 


    # Print the min item
    # place the min item in $t3 for printing
    addi $t3, $t2, 0 # ERROR: min is in $t2 not $t1
    addi $t4, $v0, 0 # ERROR: not saving the pointer to the min element
    # Print an integer followed by a newline
    li   $v0, 1         # system call code for print_int
        addi $a0, $t3, 0        # print $t3
        syscall             # make system call

    li   $v0, 4         # system call code for print_string
        la   $a0, newl      
        syscall             # print newline

    #Calculate and print the index of min item
    la  $a0, array
    sub $t3, $t4, $a0 # ERROR: sub should used not add
    srl $t3, $t3, 2 

    # Place the min index in $t3 for printing   

    # Print the min index
    # Print an integer followed by a newline
    li   $v0, 1         # system call code for print_int
        addi $a0, $t3, 0        # print $t3
        syscall             # make system call

    li   $v0, 4         # system call code for print_string
    la   $a0, newl      # 
    syscall             # print newline

    # End of main, make a syscall to "exit"
    li   $v0, 10        # system call code for exit
    syscall             # terminate program


#######################################################################
###   Function printArray   ### 
#Input: Array Address in $a0, Number of elements in $a1
#Output: None
#Purpose: Print array elements
#Registers used: $t0, $t1, $t2, $t3
#Assumption: Array element is word size (4-byte)
printArray:
    addi $t1, $a0, 0    #$t1 is the pointer to the item
    sll  $t2, $a1, 2    #$t2 is the offset beyond the last item
    add  $t2, $a0, $t2  #$t2 is pointing beyond the last item
l1: 
    beq  $t1, $t2, e1
    lw   $t3, 0($t1)    #$t3 is the current item
    li   $v0, 1         # system call code for print_int
        addi $a0, $t3, 0        # integer to print
        syscall             # print it
    addi $t1, $t1, 4
    j l1            # Another iteration
e1:
    li   $v0, 4         # system call code for print_string
        la   $a0, newl      # 
        syscall             # print newline
    jr $ra          # return from this function


#######################################################################
###   Student Function findMin   ### 
#Input: Lower Array Pointer in $a0, Higher Array Pointer in $a1
#Output: $v0 contains the address of min item 
#Purpose: Find and return the minimum item 
#              between $a0 and $a1 (inclusive)
#Registers used: $t0 (counter), $t1 (max add), $t2 (min), $v0 (min pos), $t3 (current item)
#Assumption: Array element is word size (4-byte), $a0 <= $a1
findMin:
    lw, $t2, 0($a0)         # initialise min (value) to the lower bound  
    addi $t0, $a0, 0    # initialise $t0 (current pointer) to lower bound 
    addi $t1, $a1, 0    # initialise $t1 (add of end of array) to upper bound 
Loop:
    slt $t4, $t1, $t0
    bne $t4, $zero, End     # branch to end if upper < lower

    lw, $t3, 0($t0)     # store the content of the lower array pointer, ERROR: t0 should be used not a0
    slt $t4, $t3, $t2   # if current ($t3) < min ($t2), store 1 in $t4
    beq $t4, $zero, LoopEnd # if it is 0, go to LoopEnd

    addi $t2, $t3, 0    # store content ($t3) as minimum ($t2)
    addi $v0, $t0, 0        # store the address of min

LoopEnd:
    addi $t0, $t0, 4       # increments current pointer lower bound 
    j Loop         # Jump to loop 
End:    
    jr $ra          # return from this function
person Eraklon    schedule 28.02.2020