MIPS组装 - 转换字母大小写和打印问题

时间:2016-10-06 16:00:04

标签: assembly mips

我正在尝试在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

1 个答案:

答案 0 :(得分:0)

(评论的答案摘要:)

最初的问题是符号名称中的拼写错误(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表,并想象大写/小写字母值的二进制表示,你会发现每个字母值具有相同的位模式,除了第5位(值32)。因此,对于字母而言,只需将xor $t1,$t1,32翻转到sb $t1, ($t4)而不进行分支(或验证该值至少为> =' A')而不是+ -32。

同样在当前代码中,两个分支都具有相同的continue:,在编写第一个版本后查找此类重复项并通过在'taxonomies' => array('portfolio_category', 'post_tag') 标签处移动这两个写入来重构代码。如果你经常寻找可重复使用的代码片段,并将它们重构出来,或者将指令组转换成可调用的程序,那么你的代码将具有更少的重复性,总体上将会更短(对于一个更复杂的执行流程逻辑的价格)附加电话)。更短的代码=更少的调试(通常,不保证)。