2013-12-03 2 views
2

Это функция для части программы, которая позволяет играть в Быков и Коровы. Основные прыжки и ссылки на метку 'guess' и далее, чтобы получить правильное входное значение. Теперь сама функция работает правильно, но у меня возникают проблемы с ее возвратом к основному, когда это будет сделано. Я уверен, что правильно установил указатель стека, чтобы правильный адрес возврата в main был загружен в $ ra, когда пришло время, но он все равно дает мне ошибку счетчика программ, а тестирование показало мне, что ошибка счетчика действительно происходит, когда он пытается вернуться к основному.Указатель стека/Ошибка счетчика программ MIPs

Поскольку сам вызов функции использует стек, я проверил, чтобы у меня был загружен $ right из правого пространства в $ sp (в этом случае 0 ($ sp) должен содержать основной $ ra) и это кажется правильным, но ошибка счетчика программ по-прежнему преобладает во время выполнения.

Я был бы признателен за любые материалы по этому вопросу!

#Gets user's guess and checks 

.data 
prompt:   .asciiz "\nEnter four unique hexadecimal digits: " 
invalidInput: .asciiz "\nInvalid guess: must be four unique hexadecimal digits" 
validInput: .byte  '0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F','a','b','c','d','e','f' 
input: .word 4 

.text 

#Get the user input 
guess: 
addi $sp, $sp, -4 #Here is where I save the return address to main 
sw $ra, 0($sp)  # 

la $a0, prompt 
li $v0, 4  
syscall   

la $a0, input 
li $a1, 5  
li $v0, 8  
syscall   

jal checkAll  #Jumps to the only other call that affects the $sp 

#This is the instruction that is flooping around with my program counter, although it seems right! 
lw $ra, 0($sp) #When the function is done, load the return address to main 
addi $sp, $sp, 4 
jr $ra   #jump back to main 

#Call to quit - for testing 
li $v0, 10 
syscall   

#Makes room and gets input validated 
checkAll: 
addi $sp, $sp, -8  #This function alters the $sp for it's own calls 
sw $ra, 8($sp) 
sw $a0, 4($sp) 

li $s0, 3 
la $a1, validInput 
b isValid 

lw $a0, 4($sp)  #But then it restores the $sp and is able to link back to the 'guess' call 
lw $ra, 8($sp) 
addi $sp, $sp, 8 
jr $ra 

#Checks each character from the input agaisnt the valid input characters, basically if  the input is hexadecimal 
isValid: 
blt $s0, $0, unique 

la $t0, ($a0) 
add $t1, $s0, $0 
add $t2, $t1, $t0 
lb $t3, ($t2) 
li $s1, 21 

#Checks each input character agaisnt each valid input character  
checkNum: 
blt $s1, $0, invalid    
la $t0, ($a1) 
add $t1, $s1, $0 
add $t2, $t1, $t0 
lb $t4, ($t2) 
bne $t3, $t4, notEqual 
j equal 

#Character from input is a valid character   
equal: 
add $s0, $s0, -1 
j isValid 

#Character from input is not a valid character 
notEqual: 
add $s1, $s1, -1 
j checkNum 

#Check if the input is not duplicated 
unique: 
la $t0, ($a0) 
lb $t1, 0($t0) 
lb $t2, 1($t0) 
lb $t3, 2($t0) 
lb $t4, 3($t0) 

beq $t1, $t2, invalid 
beq $t1, $t3, invalid 
beq $t1, $t4, invalid  
beq $t2, $t3, invalid 
beq $t2, $t4, invalid 
beq $t3, $t4, invalid 

jr $ra 

invalid: 
la $a0, invalidInput 
li $v0, 4 
syscall 

j guess 
+0

Я надеюсь, что вы не * только * начать работу над проектом семестра! Четверг не за горами, а MIPS - суровая любовница ... – RobertB

ответ

1

Несколько вещей здесь.

Во-первых, вы используете .word 4 для хранения input. Это выделяет одно слово со значением 4, которое, вероятно, не то, что вы хотите. Я изменил это на .space 256.

Далее вы используете системный вызов 8, чтобы прочитать прочитанное в строке с 5 символами. Это не будет работать, так как правильный ввод не менее 6 символов, например .: "1234\n\0".

Так или иначе, ваша проблема заключается в том, что при возврате с вашей функции checkAll вы забыли восстановить $ra и прирастить $sp. Ниже в филиалах недействительным я изменил jr $ra на:

lw $ra, 8($sp) 
addi $sp, $sp, 8 
jr $ra 

Это сделало путь исполнения Вашего счастливого выполнить без этой конкретной ошибки, но программа, кажется, страдает от некоторой путаницы понятий. Например, вы обрабатываете checkAll в качестве функции, позвонив с jal и возвращаясь с jr, но в недопустимом случае функции вы j прямо на guess. Эта неравномерная обработка является ожидающей катастрофой и, вероятно, приведет к коррупции в стеках.

0

Одна из проблем заключается в следующем:

checkAll: 
addi $sp, $sp, -8  #This function alters the $sp for it's own calls 
sw $ra, 8($sp) 
sw $a0, 4($sp) 

Вы резерве 8 байт в стеке, но сохранить $ra и $a0 неправильно. Код должен быть:

addi $sp, $sp, -8  #This function alters the $sp for it's own calls 
sw $ra, 0($sp) 
sw $a0, 4($sp) 

То же самое, прежде чем вернуться из процедуры checkAll.

lw $a0, 4($sp)  #But then it restores the $sp and is able to link back to the 'guess' call 
lw $ra, 8($sp) 
addi $sp, $sp, 8 
jr $ra 

Должно быть

lw $a0, 4($sp) 
lw $ra, 0($sp) 
addi $sp, $sp, 8 
jr $ra 
Смежные вопросы