【问题标题】:Implement in MIPS assembler the check if a given fiscal code is correct在 MIPS 汇编器中实现检查给定的财务代码是否正确
【发布时间】:2013-05-30 02:07:41
【问题描述】:

好吧,我有一个作业要做,它是这样的:在 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***

【问题讨论】:

  • 我对你为什么 la $a0, Array 一直在你的循环中有点困惑。当您之前执行此操作然后将 0($t0) 放入其中时。也许我在这里让自己感到困惑。你能举一个输入和预期输出的例子吗?
  • 例如“Kynmmm91s11z236p”这是一个存储在数组 1 中的财政代码,然后我们创建数组 2,我们从键盘获取值。最后我们比较两个数组,如果两者相等,那么财务代码是正确的。
  • 您将财务代码存储在代码的什么位置?
  • 你能解释一下这行吗? "支票应重新计算财政代码末尾的"支票信",并将其与存在的代码进行比较。"
  • 我大致添加了:Array1: .ascii "Kynmmm91s11z236p" 因为我不知道该怎么做。

标签: assembly comparison mips


【解决方案1】:

第二次编辑:

好的,这对于您的示例检查代码现在可以正常工作,但我不能保证没有隐藏的错误或任何错误。给定 16 个字符的财政代码,它将打印正确或不正确的控制代码。

这是非常重复的,因为我在奇怪的位置找不到很多模式,我不想做任何复杂的事情。我把它写得很简单,并把它彻底评论了。

如有任何其他问题或 cmets,请随时提出。

# 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

【讨论】:

  • translate.google.com/…上有一个关于如何计算意大利税码的描述
  • 我从教授那里得到的回应是“支票应该重新计算财政代码末尾的“支票信”,并将其与现有代码进行比较。”任务是您从键盘输入财务代码,例如 Kynmmm91s11z236p :“p”是检查代码,一个使用所有其他字母计算的字母。您应该根据第一个链接中的说明进行计算。然后你将你计算的结果与你从用户那里得到的字母进行比较并输出结果。
  • 非常感谢 Wazy 到目前为止你帮了我很多。
  • 这实际上看起来有点令人困惑,除非我读错了。所以我们有一个输入财政字符串和一个存储在内存中。然后,我们通过重新计算校验码来验证输入,然后将其与内存中的原始校验码进行比较,还是?如果您仍在处理它,请将您的最新代码放在上面。
  • 不,实际上我首先理解错了。我们只有一个从键盘获取的代码作为输入。例如 Kynmmm91s11z236p 。所以最后一个字母字符是基于前面的 16 个字母。奇怪的 ………。甚至…………………….. Sum : = Number Number/26 = 最后一个字母。因此,我们必须将作为键盘输入的最后一个字符与我们基于前 15 个字符的计算进行比较。这是您可以看到dotnethell.it/articles/CalcoloCodiceFiscale.aspx的链接
【解决方案2】:

这就是它可能的样子..

.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.

【讨论】:

  • 先用另一种语言编写算法。 C/Java等
  • 我不明白这一点:6 怎么可能处于奇数位置,因此 = 15?检查我发布的修改后的代码,它大部分是完整的,并计算出 6。
  • 控制码应始终在奇数表中查找。我将在代码中解决这个问题。
  • 非常感谢 Wazy .. 我很佩服你的努力.. 很有帮助
猜你喜欢
  • 2017-03-28
  • 1970-01-01
  • 2017-12-20
  • 1970-01-01
  • 2018-10-22
  • 2015-03-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多