0

我正在编写一个程序,它采用罗马数字(最多 12 个字符)并将其转换为十进制值。我能够成功地进行此转换并逐个字符地读取每个值,但是当输入的字符串不是 12 个字符时,我的值总是比实际值大 1000,我确定这是由于通过评估子例程的额外循环(如果没有匹配,则进入转换 M = 1000 的过程)。

我认为这与我在少于 12 个字符时读取用户字符串的方式有关。据我了解,读取的字符串系统调用代码会继续执行,直到它到达一个 '\n' 字符,并将该字符及其剩余空间转换为 0 个字符,因此检查下一个字符是否不等于 0 应该可以工作因为我不希望 0 出现在用户的输入中。我确实意识到如果在“评估”期间没有匹配,我可以通过跳转到 tailLoop 来修复我的代码,但我想了解为什么我目前的代码不起作用。

以下代码不包含我的大部分程序(完整发布会很长),仅足以理解我尝试使用的逻辑过程。这是家庭作业,以防它影响你想如何回答问题。

# Program to translate Roman Numerals to decimal values

.data
    numeralString:
        .space 13
# End Strings

.text   # Begin Program
.globl main

main:
    li $v0, 8 # read string from user at next syscall
    la $a0, numeralString
    li $a1, 13
    syscall

    la $t0, numeralString # take input string and store in $t0
    move $t1, $t0 # creating a copy of base register
    lb $t2, 0($t0) # loads first byte (character) into $t2

    jal evaluate # calls evaluate subroutine.  String passed via $t0 (first byte/character specified in $t2)
             # interger value returned via $v1

    li $v0, 1 # print result value from $v1 at next syscall
    move $a0, $v1
    syscall

exit:   # Exit Program in next syscall

    li $v0, 10 # exit program in next syscall
    syscall

evaluate: # matches numeral in string to correct subroutine
    lb $t3, 1($t0)
    beq $t2, 'M', mChar

mChar:
    addi $v1, $v1, 1000
    # beq $t3, 'C', cSlot
    j tailLoop

tailLoop:
    move $t2, $t3 # $t2 now holds next character of string
    addi $t0, $t0, 1
    bnez $t2, evaluate # Go back to evaluate if next character exists
    jr $ra
4

1 回答 1

0

据我了解,读取字符串系统调用代码会继续执行,直到它到达一个 '\n' 字符,并将该字符及其剩余空间转换为 0 个字符

不。

如果您查看spim 源代码,您会看到read_input在系统调用的情况下调用的函数

在 Unix 文件上模拟 [s] fgets(不是gets)的语义。

根据 CPlusPlus.com

换行符使 fgets 停止读取,但它被函数视为有效字符并包含在复制到 str 的字符串中。

这可以通过检查 spim 代码来确认。

于 2016-03-29T22:36:24.423 回答