0

ローマ数字 (最大 12 文字) を 10 進数値に変換するプログラムを作成しています。この変換を正常に実行し、各値を文字単位で読み取ることができますが、入力文字列が 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、syscall の場合に呼び出される関数がわかります。

Unix ファイルで fgets (gets ではない) のセマンティクスをシミュレートします。

CPlusPlus.com によると:

改行文字は fgets の読み取りを停止させますが、関数によって有効な文字と見なされ、str にコピーされる文字列に含まれます。

これは、spim コードを調べることによって確認されます。

于 2016-03-29T22:36:24.423 に答える