質問

I have a program that will capitalize all lowercase letters and lowercase all the uppercase letters entered in a string by the user. It does this by adding or subtracting 32 from the character value to get the desired character. My problem is that it doesn't change anything in the string. Any suggestions on what to change?

.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
役に立ちましたか?

解決

You are using $a0as a character, such as here:

slti $t2, $a0, 91

but it is never filled with the character. At the moment, it contains a memory address, not a character.

You should load the character using lb and store it back after making it upper/lowercase using sb.

Feel free to add a comment if you want a code example.

Edit: the changes in the relevant part of the code:

...
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
...

他のヒント

It's easy to forget that in assembly, you can't do this:

if something
    do this
else
    do that

There is no "else", only shudder Goto.

So in this code:

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

When you branch to upper, it adds 32. Then it subtracts 32, because execution progressed to the next line. So your code capitalizes lower case, but does nothing to uppercase.

You need to add a jump to the first instruction after your if/then/else equivalent:

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

In fact, you should probably get rid of the bne altogether - it's redundant. If beq doesn't branch, then it's not equal. So this would be the finished product:

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

Hope that helps!

(Edit: @Patrik is right too, you need to "dereference" $a0. My example doesn't take that into account.)

here is my code: it works perfectly

.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 
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top