2

好吧,我有一个任务要做它是这样的:在 MIPS 汇编器中实现检查给定的意大利财政代码是否正确。支票应重新计算财务代码末尾的“支票信”,并将其与现有代码进行比较。

当你用汇编程序编写它时,需要考虑一些棘手的事情: - 你如何在 MIPS 程序集中存储一个数组?- 你怎么能要求用户输入?(提示:使用系统调用,你会在网上找到很多例子如何做到这一点) - 你如何逐个字符地遍历数组?- 你怎么能计算出正确的总和?- 你如何将结果与给定的字母进行比较?
到目前为止我所尝试的只是输入和打印,不知道如何做剩下的。

.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

第二次编辑:

好的,这对于您的示例检查代码现在可以正常工作,但我不能保证没有隐藏的错误或任何错误。给定 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 回答
1

这就是它可能的样子..

.data 

                ArraySpace: .space 18
                Prompt: .asciiz "Enter the fiscal code: "  
                Line: .asciiz "\n"

    .text

    # $a0 = buffer, $a1 = length

    main:   
        la $a0, Prompt          # user prompt
        li $v0, 4               # print string
        syscall

        li $v0, 8               # read string to store into ArraySpace 
        la $a0, ArraySpace      # load address of fiscal value attempt
        li $a1, 18              # length 16 + '\n' + '\0'
        syscall

        la $a0, ArraySpace      # load user string
        li $v0, 4               # print string
        syscall

        # An example of Fiscal code = Kynmmm91s11z236p

我实际上对MIPS一无所知。所以我将编写计算财政代码最后一个字母的算法..

I dont know how to translate this algorithm in MIPS.

    Formula for the calculation of last letter of Fiscal code.
    Even position Values ………….
    ODD position Values …………….
    Sum : = Number/26 =  last letter.

   Fiscal Code  : Kynmmm91s11z236p

    EVEN positions values
    K   n     m    9    s   1   2    6  
    10+ 13 +  12 + 9  +  18+ 1 +  2  +6 =  71 

    ODD  position values
    Y       m      m      1    1     z    3 
    24  + 18 +  18 +0 +  0 +23 + 7 =  90
    I61/26 = 6 
   As 6 is at odd position so 6 = 15.
 According to the last letter table 15 = P. Which is correct.
于 2013-06-02T15:15:40.880 回答