2

それは次のようなものです: MIPS アセンブラーで、特定のイタリア会計コードが正しいかどうかのチェックを実装します。小切手は、会計コードの末尾にある「小切手」を再計算し、存在するコードと比較する必要があります。

アセンブラーで記述する場合、考慮すべきいくつかの注意点があります。 - MIPS アセンブリーに配列をどのように格納しますか? - どのようにユーザー入力を求めることができますか? (ヒント: syscall を使用してください。Web 上にその方法の例がたくさんあります) - 配列を 1 文字ずつ反復処理するにはどうすればよいでしょうか? - どうすれば正しい合計を計算できますか? - 結果を与えられた文字とどのように比較できますか?
私がこれまでに試したことは、入力と印刷を取得することだけで、残りの方法はわかりません。

.data 
       Array1:  .ascii   "Kynmmm91s11z236p"
        Array2: .space 16 
            Promt: .asciiz "Enter the fiscal code:\n"  
            Line: .asciiz "\n"

.text

main:

    la $a0,Promt    
    la $t2,Array1
    li $v0,4   # prints what ever is in prompt with syscall
    syscall

    move $a0,$t2
    li $v0,4   # prints what ever is in prompt with syscall
    syscall

   la $a0,Array2    
   li $a1,20   
    li $v0,8    
   syscall

    la $t0,Array2  # BASE ADDRESS OF ARRAY   
    li $t1,4    
    lw $a0,0($t0) #***MOVED THIS OUT***     
    Loop:
        add $t0,$t0,$t1         
            beq $a0,0, Exit         
            la $a0, Array2       
            li $v0,4        
            syscall         

            li $a0, 0  #****ADDED THIS LINE****         
            j Loop

    Exit:
        li $v0,10   
            syscall

           # ***Kynmmm91s11z236p***
4

2 に答える 2

2

2番目の編集:

さて、これはあなたの例のチェックコードに対して正しく機能するようになりましたが、隠れたバグや間違いがないことを保証することはできません. 16 文字のフィスカル コードを指定すると、制御コードが正しいか正しくないかが出力されます。

奇妙な位置に非常に多くのパターンを見つけることができず、複雑にするために何もしたくなかったため、非常に反復的です. かなりシンプルにして、徹底的にコメントしました。

ご質問やご意見がございましたら、お気軽にお問い合わせください。

# Italian Fiscal Code Calculation in MIPS

        .data
            ArraySpace:     .space 18
            lookupTableOdd: .ascii "10579"
            msgOk:          .asciiz "\nCorrect control code!"
            msgFail:        .asciiz "\nIncorrect control code!"
        .text

main:
    li $v0, 8                       # read string to store into ArraySpace 
    la $a0, ArraySpace              # load address of fiscal value attempt
    li $a1, 18                      # length 16 + '\n'
    syscall                         # tell system to read string                
    addi $t2, $a1, -2               # length of string
    li $t3, 0                       # i = 0 (our string iterator)
    jal loop                        # actually loop through input string

    li $t9, 26                      # load 26 for divison
    div $t5, $t9                    # divide total in $t5 by 26
    mflo $t4                        # move result into $t4 

    jal controlCode                 # calculate control code
    move $t5, $t4                   # move our calculated check code to $t5
    jal checkCode                   # check control code

    li $v0, 10                      # exit code
    syscall                         # terminate nicely

checkCode:
    addi $t2, $t2, -1               # backup to last index in string
    lbu $t4, ArraySpace($t2)        # load the control code of the input string  (last index)
    blt $t4, 65, endLoop            # should not get something below 65
    bgt $t4, 122, endLoop           # not valid character above 122
    addi $t4, $t4, -65              # get alphabet value 0-25
    bge $t4, 32, case_convert_ch    # if a-z we have to sub 32
    beq $t5, $t4, checkOk           # checkcode is equal to calculated code
    j checkFail                     # else fail

checkFail:
    li $v0, 4                       # print fail
    la $a0, msgFail                 # load failed code message
    syscall                         # print it
    j endLoop                       

case_convert_ch:
    addi $t4, $t4, -32              # make lowercase 'A'-'a'=-32
    beq $t4, $t5, checkOk           # if equal print ok
    j checkFail                     # else fail

controlCode:
    bgt  $t4, 4, checkDigit         # >4 is two digit value
    lbu  $t4, lookupTableOdd($t4)   # fetch corresponding value
    addi $t4, $t4, -48              # get digit value
    j endLoop

checkDigit:                         # this is for 5 to 9 in odd positions
    sub $t4, $t4, 5                 # value - 5
    mul $t9, $t4, 2                 # multiply this by 2
    li $t4, 13                      # the base is 13
    add $t4, $t4, $t9               # 13 + factor of 2
    j endLoop

case_convert_cc:
    addi $t4, $t4, -32              # uppercase: 'A'-'a'=-32
    bgt  $t4, 4, oddDigit           # >4 is two digit value
    lbu  $t4, lookupTableOdd($t4)   # fetch corresponding value
    addi $t4, $t4, -48              # get digit value
    j endLoop

checkOk:
    li $v0, 4                       # print string
    la $a0, msgOk                   # load ok message
    syscall                         # print it
    j endLoop

loop:
    bge  $t3, $t2, endLoop          # if greater than length of string end
    andi $t8, $t3, 1                # logical AND result into $t2 (even = 0, odd = 1)
    beq $t8, $zero, evenLoop        # on even positions goto evenLoop
    j oddLoop                       # on odd positions goto oddLoop

evenLoop:
    lbu $t4, ArraySpace($t3)        # load the i index of the input string
    blt $t4, 48, endLoop            # should not get something below 48
    bgt $t4, 57, evenCharLoop       # not a digit
    addi $t4, $t4, -48              # get digit value
    j continueLoop

oddLoop:
    lbu $t4, ArraySpace($t3)        # load the i index of the input string
    blt $t4, 48, endLoop            # should not get something below 48
    bgt $t4, 57, oddCharLoop        # not a digit

    addi $t4, $t4, -48              # get digit value
    bgt  $t4, 4, oddDigit           # >4 is two digit value
    lbu  $t0, lookupTableOdd($t4)   # fetch corresponding value
    addi $t4, $t0, -48              # get digit value
    j continueLoop

oddDigit:                           # this is for 5 to 9 in odd positions
    sub $t4, $t4, 5                 # value - 5
    mul $t9, $t4, 2                 # multiply this by 2
    li $t4, 13                      # the base is 13
    add $t4, $t4, $t9               # 13 + factor of 2
    j continueLoop

evenCharLoop:
    blt $t4, 65, endLoop            # should not get something below 65
    bgt $t4, 122, endLoop           # not valid char
    addi $t4, $t4, -65              # get alphabet value
    bge $t4, 32, case_convert_even  # if a-z we have to sub 32
    add $t5, $t5, $t4               # add the alpha value A-Z to our sum
    add $t3, $t3, 1                 # i++
    j loop

oddCharLoop:
    blt $t4, 65, endLoop            # should not get something below 65
    bgt $t4, 122, endLoop           # not valid char
    addi $t4, $t4, -65              # get alphabet value
    bge $t4, 32, case_convert_odd   # if a-z we have to sub 32
    j oddProcess

## this should probably be done better but I did not find many patterns ##
oddDigitCheck:
    ble  $t4, 9, oddDigit           # F>=x<=J is two digit value of factor 2
    sub $t4, $t4, 10                # >=K
    blt $t4, 2, KL                  # 0-K 1-L
    blt $t4, 4, MN                  # 2-M 3-N
    beq $t4, 4, O                   # 4-O
    blt $t4, 7, PQ                  # 5-P 6-Q
    beq $t4, 7, R                   # 7-R
    blt $t4, 11, STU                # 8-S 9-T 10-U
    beq $t4, 11, V                  # 11-V
    beq $t4, 12, W                  # 12-W
    blt $t4, 16, XYZ                # 13-X 14-Y 15-Z

oddProcess:
    bgt  $t4, 4, oddDigitCheck      # >E could be two digit value
    lbu  $t0, lookupTableOdd($t4)   # fetch corresponding value (A-E)
    addi $t0, $t0, -48              # get digit value
    add $t5, $t5, $t0               # add the digit to our sum
    add $t3, $t3, 1                 # i++
    j loop

case_convert_even:
    addi $t4, $t4, -32              # to uppercase: 'A'-'a'=-32
    j continueLoop

case_convert_odd:
    addi $t4, $t4, -32              # to uppercase: 'A'-'a'=-32
    j oddProcess

endLoop:
    jr $ra                          # jump and return

XYZ:
    sub $t4, $t4, 13                # X or Y or Z
    li $t9, 25                      # base is 25
    sub $t4, $t9, $t4               # 25 - (0,1,2)
    j continueLoop

W:
    li $t4, 22                      # W = 22
    j continueLoop

V:
    li $t4, 10                      # V = 10
    j continueLoop

STU:
    sub $t4, $t4, 8                 # S or T or U
    mul $t9, $t4, 2                 # mult by 2
    li  $t4, 12                     # base of 12        
    add $t4, $t4, $t9               # add factor
    j continueLoop

R:
    li $t4, 8                       # R = 8
    j continueLoop

PQ:
    sub $t4, $t4, 5                 # P or Q
    mul $t9, $t4, 3                 # mult by 3
    li  $t4, 3                      # base of 3     
    add $t4, $t4, $t9               # add factor
    j continueLoop

O:
    li $t4, 11                      # O = 11
    j continueLoop

MN:
    sub $t4, $t4, 2                 # M or N
    mul $t9, $t4, 2                 # mult by 2
    li  $t4, 18                     # base of 18        
    add $t4, $t4, $t9               # add factor
    j continueLoop

KL:
    mul $t9, $t4, 2                 # mult by 2
    li  $t4, 2                      # base of 2     
    add $t4, $t4, $t9               # add factor
    j continueLoop

continueLoop:
    add $t5, $t5, $t4               # add the digit to our sum
    add $t3, $t3, 1                 # i++
    j loop
于 2013-05-30T06:58:10.177 に答える