MIPS 汇编 - 转换字母大小写和打印问题

MIPS Assembly - Convert letter case and print issue

我正在尝试用 MIPS 汇编编写一个程序来反转给定字符串的字母大小写。我想我已经成功转换了下面代码中的字符串,但它不会打印。我想我转换它是因为当我 运行 它一次一条指令时,它会通过正确的循环次数。非常感谢任何有关理解如何打印新字符串的帮助。下面是我已经编写的代码,以及我收到的错误消息。非常感谢大家!

.data

testString: .asciiz "TEST"
revString: .space 32
errorMessage: .asciiz "error, try again"

.text

la $t4, revString
la $t0, testString

checkCase:
    lb $t1, ($t0) #assigns char of string to $t1
    beqz $t1, end #ends loop
    li $t2, 'a'
    li $t3, 'A'
    bge $t1, $t2, toUpper #confirms lowercase letter
    bge $t1, $t3, toLower #confirms uppercase letter
    j error #jumps to error if not a valid letter

toLower:
    addi $t1, $t1, 32 #converts upper to lowercase
    sb $t1, ($t4) #stores letter in $t4
    j continue #iterates both $t0 and $t4

toUpper:
    sub $t1, $t1, 32 #converts lower to uppercase
    sb $t1, ($t4) #stores letter in $t4
    j continue #iterates both $t0 and $t4

continue: #jumps to next letter in testString and revString
    add $t0, $t0, 1
    add $t4, $t4, 1
    j checkCase

error:
    la $a0, errorMessage #prints error message
    li $v0, 4
    syscall

end: #prints reversed letter case string
    #move $t4, revStr #assigns string in $t4 to revStr
    la $a0, ($t4)
    li $v0, 4
    syscall

尝试打印 $t4 无效,如果我尝试使 revStr 等于 $t4 的值,我收到此错误消息:

line 42 column 12: "revStr": operand is of incorrect type

(评论的答案摘要:)

最初的问题是符号名称拼写错误(revStr 而不是 revString),并且使用错误的指令加载缓冲区地址以打印结果,结果应该如下所示:

end: #prints reversed letter case string
    la $a0, revString  # assign memory address of result string
    li $v0, 4
    syscall

在这些修复之后,代码中仍然至少存在一个错误,将 revString: .space 32 替换为:

后将变得可见
    # 16 bytes space initialized to 33
revString: .byte 33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33

(修复非常明显,一旦您了解了 asciiz 字符串如何存储在内存中,以及内存如何查看 end: 标签,只需检查调试器)。


以及一些高级提示:

在早期的 CPU 时代,代码的性能非常重要,因此在编写任何指令之前,程序员通常会花大量时间思考他真正想要实现的目标以及实现该目标的选项。

在您的情况下,您想将 'A'(和类似的)变成 'a',反之亦然。 'A' 是值 65(ASCII 定义),'a' 是值 97,所以你的 +-32 是正确的想法。但是如果你更仔细地检查 ASCII table,并想象一下 upper/lower 大小写字母值的二进制表示,你会发现除了第 5 位(值 32)外,每个字母值都有相同的位模式.因此,除了 +-32 之外,您还可以将字母翻转 xor $t1,$t1,32 而无需分支(或验证该值至少为 >= 'A')。

此外,在当前代码中,两个分支具有相同的 sb $t1, ($t4),在编写第一个版本后查找此类重复项并通过将这两个写入移动到 continue: 标签来重构代码。如果您经常寻找可重用的代码片段,并将它们重构出来,或者将指令组转换为可调用的过程,您的代码将减少重复,并且总体上会更短(以更复杂的执行流逻辑为代价)与额外的电话)。更短的代码 = 更少的调试(通常,不保证)。