2013-10-13 2 views
2

У меня есть программа, которая будет использовать все буквы в нижнем регистре и в нижнем регистре все заглавные буквы, введенные пользователем в строку. Он делает это, добавляя или вычитая 32 из значения символа, чтобы получить желаемый символ. Моя проблема в том, что она ничего не меняет в строке. Любые предложения по изменению?Дело сортировка в mips

.data 
prompt: .asciiz "\n\nEnter an string of characters: " 
result: .asciiz "\n\nHere is the string you entered: " 
after_sort: .asciiz "\n\nHere is the string after the case sorting: " 
buffer: .space 80 
.text 

main: 

#Prints the prompt string 
li $v0, 4 
la $a0, prompt 
syscall 

#reads string from user and saves in $a0 
li $v0, 8 
la $a0, buffer 
li $a1, 80 
syscall 

#Prints the result string 
li $v0, 4 
la $a0, result 
syscall 

#Prints the string entered by the user 
la $a0, buffer 
li $v0, 4 
syscall 


li $t0, 0 # t0 = i = 0 
for_loop: 
slti $t1, $t0, 80 # t1 = 1 if and only if t0 < 80 
beq $t1, $0, for_loop_done 

slti $t2, $a0, 91 
li $t3, 1 
beq $t2, $t3, upper #if the character value is less than 91 branch to upper addition 
bne $t2, $t3, lower 

upper: 
addi $a0, $a0, 32 #adds 32 to the character value to lowercase it 

lower: 
subi $a0, $a0, 32 #subtracts 32 from the character value to capitalize it 

addi $t0, $t0, 1 

j for_loop 
for_loop_done: 

#Prints the result string 
li $v0, 4 
la $a0, after_sort 
syscall 

#Prints the string entered by the user 
la $a0, buffer 
li $v0, 4 
syscall 

exitProgram: li $v0, 10 # system call to 
    syscall   # terminate program 

ответ

0

Вы используете $a0 как характер, например, здесь:

slti $t2, $a0, 91 

, но она никогда не заполняется с характером. На данный момент он содержит адрес памяти, а не символ.

Вы должны загрузить символ с помощью lb и сохранить его обратно после того, как он сделал верхний/нижний регистр, используя sb.

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

Edit: изменения в соответствующей части кода:

... 
li $t0, 0 # t0 = i = 0 
for_loop: 
slti $t1, $t0, 80 # t1 = 1 if and only if t0 < 80 
beq $t1, $0, for_loop_done 

lb $t4, 0($a0) 
beqz $t4, for_loop_done 
beq $t4, 10, for_loop_done 
slti $t2, $t4, 91 
li $t3, 1 
beq $t2, $t3, upper #if the character value is less than 91 branch to upper addition 
bne $t2, $t3, lower 

upper: 
addi $t4, $t4, 32 #adds 32 to the character value to lowercase it 
j done 

lower: 
addi $t4, $t4, -32 #subtracts 32 from the character value to capitalize it 
done: 

addi $t0, $t0, 1 

sb $t4, 0($a0) 
addi $a0, $a0, 1 

j for_loop 
for_loop_done: 

#Prints the result string 
... 
+0

Я добавил lb $ t4, 0 ($ a0) выше строки 39, переключил $ a0 на $ t4 на строки addi и subi, к которым условные операторы привязаны к и добавили sb $ t4, 0 ($ a0) ниже строки 48 , и addi $ a0, $ a0, 1 ​​ниже предыдущего добавления. Он меняется только с нижнего регистра на верхний, а не наоборот. Какие-либо предложения? – user2837034

+0

'lb $ t4, 0 ($ a0)' должен идти на 2 строки выше, над тестом slti (и изменить $ a0 на $ t4 в этом тесте). Кроме того, тест для nul символов сразу после инструкции загрузки: 'beqz $ t4, for_loop_done'. Наконец, после верхнего, нижний всегда выполняется.После того, как верхняя часть будет выполнена, перейдите к нижней инструкции. – Patrik

+0

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

0

Это легко забыть, что в сборке, вы не можете сделать это:

if something 
    do this 
else 
    do that 

Там нет «еще ", только содрогаться Перейти.

Так что в этом коде:

slti $t2, $a0, 91 
li $t3, 1 
beq $t2, $t3, upper #if the character value is less than 91 branch to upper addition 
bne $t2, $t3, lower 

upper: 
addi $a0, $a0, 32 #adds 32 to the character value to lowercase it 

lower: 
subi $a0, $a0, 32 #subtracts 32 from the character value to capitalize it 

addi $t0, $t0, 1 

Когда филиал в upper, он добавляет 32. Тогда вычитает 32, потому что выполнение прогрессировала к следующей строке. Таким образом, ваш код набирает строчные буквы, но ничего не делает в верхнем регистре.

Вы должны добавить переход к первой инструкции после вашей, если/Then/Else эквивалент:

upper: 
addi $a0, $a0, 32 #adds 32 to the character value to lowercase it 
j done # No, I don't want to subtract it again! 

lower: 
subi $a0, $a0, 32 #subtracts 32 from the character value to capitalize it 

done: 
addi $t0, $t0, 1 

На самом деле, вероятно, вы должны избавиться от bne вообще - это излишним. Если beq не ветвится, то это не равно. Таким образом, это будет готовый продукт:

slti $t2, $a0, 91 
li $t3, 1 
beq $t2, $t3, upper #if the character value is less than 91 branch to upper addition 

# Otherwise, it's lower 
subi $a0, $a0, 32 #subtracts 32 from the character value to capitalize it 
j done 

upper: 
addi $a0, $a0, 32 #adds 32 to the character value to lowercase it 

done: 
addi $t0, $t0, 1 

Надеюсь, что это поможет!

(Edit: @Patrik прав тоже нужно «разыменования» $ a0 Мой пример не принимает это во внимание.).

0

вот мой код: он отлично работает

.data 
theString: 
.space 20 
prompt: .asciiz "Enter a string of characters: " 
.text 
main: 
li $v0, 4 
la $a0, prompt 
syscall 

li $v0, 8 
la $a0, theString 
li $a1, 20 
syscall 

li $v0, 4 
syscall 
la $t1,theString 
for: lb $a0, 0($t1) 
beqz $a0,out #to find out end of string 
beq $a0,10,out #to find out end of string 
slti $t2, $a0,91 #if $a0<91 $t2=1 
beq $t2,1,small 
beq $t2,0,capital 
capital: 
subu $a0, $a0, 32 
li $v0,11 
syscall 
addi $t1,$t1,1 
j for 
small: 
addi $a0, $a0, 32 
li $v0,11 
syscall 
addi $t1,$t1,1 
j for 
out: 
li $v0, 10 
syscall 
Смежные вопросы