Assembly 在MIPS汇编程序中实现检查给定的会计代码是否正确

Assembly 在MIPS汇编程序中实现检查给定的会计代码是否正确,assembly,comparison,mips,Assembly,Comparison,Mips,我有一个任务是这样做的:在MIPS汇编程序中实现检查给定的意大利财政代码是否正确。支票应重新计算会计代码末尾的“支票字母”,并将其与当前代码进行比较 在汇编程序中编写时,需要考虑一些棘手的问题: -如何在MIPS程序集中存储数组? -您如何请求用户输入?(提示:使用系统调用,您将在web上找到许多如何执行的示例) -如何逐字符遍历数组? -你如何计算正确的总数? -如何将结果与给定的字母进行比较? 到目前为止,我尝试的只是输入和打印,不知道如何完成其余的工作 .data Arra

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

在汇编程序中编写时,需要考虑一些棘手的问题: -如何在MIPS程序集中存储数组? -您如何请求用户输入?(提示:使用系统调用,您将在web上找到许多如何执行的示例) -如何逐字符遍历数组? -你如何计算正确的总数? -如何将结果与给定的字母进行比较?
到目前为止,我尝试的只是输入和打印,不知道如何完成其余的工作

.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***
第二次编辑:

好的,这对你的示例检查代码来说是正确的,但我不能保证没有隐藏的bug或任何错误。给定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
#MIPS中的意大利财政代码计算
.数据
阵列空间:。空间18
lookupTableOdd:.ascii“10579”
msgOk:.asciiz“\n正确的控制代码!”
msgFail:.asciiz“\n控制代码不正确!”
.文本
主要内容:
li$v0,8#读取字符串以存储到ArraySpace
la$a0,数组空间#财政值尝试的加载地址
li$a1,18#长度16+“\n”
syscall#告诉系统读取字符串
addi$t2$a1,-2#字符串长度
li$t3,0#i=0(我们的字符串迭代器)
jal循环#实际上是通过输入字符串循环
li$t9,26#加载26进行除法
div$t5,$t9#将总计$t5除以26
mflo$t4#将结果移到$t4
日航控制代码#计算控制代码
移动$t5,$t4#将我们计算的支票代码移动到$t5
日航检查代码#检查控制代码
li$v0,10#退出代码
syscall#很好地终止
检查代码:
addi$t2,$t2,-1#备份到字符串中的最后一个索引
lbu$t4,ArraySpace($t2)#加载输入字符串的控制代码(最后一个索引)
blt$t4,65,endLoop不应低于65
bgt$t4,122,endLoop#122以上无效字符
addi$t4,$t4,-65#获取字母表值0-25
bge$t4,32,如果a-z我们必须低于32
beq$t5,$t4,checkOk#checkcode等于计算代码
j检查失败#否则失败
检查失败:
li$v0,4#打印失败
la$a0,msgFail#加载失败代码消息
syscall#打印它
j端环
案例转换:
addi$t4,$t4,-32#使小写字母“A”-“A”=-32
beq$t4,$t5,勾选ok#如果相等,打印ok
j检查失败#否则失败
控制代码:
bgt$t4,4,校验位#>4是两位数的值
lbu$t4,lookupTableOdd($t4)#获取相应的值
addi$t4,$t4,-48#获取数字值
j端环
校验位:#这适用于奇数位置的5到9
低于$t4,$t4,5#价值-5
mul$t9,$t4,2乘以2
li$t4,13#基数为13
加上$t4、$t4、$t9#13+系数2
j端环
案例转换抄送:
addi$t4,$t4,-32#大写:'A'-'A'=-32
bgt$t4,4,oddDigit#>4是两位数的值
lbu$t4,lookupTableOdd($t4)#获取相应的值
addi$t4,$t4,-48#获取数字值
j端环
检查确认:
li$v0,4#打印字符串
la$a0,msgOk#加载ok消息
syscall#打印它
j端环
循环:
bge$t3,$t2,endLoop#如果大于字符串末端的长度
andi$t8、$t3、1#逻辑AND结果为$t2(偶数=0,奇数=1)
beq$t8,$零,偶数循环#偶数位置转到偶数循环
j oddLoop#在奇数位置转到oddLoop
evenLoop:
lbu$t4,ArraySpace($t3)#加载输入字符串的i索引
blt$t4,48,endLoop不应低于48
bgt$t4,57,evenCharLoop#不是数字
addi$t4,$t4,-48#获取数字值
j continueLoop
奥德洛普:
lbu$t4,ArraySpace($t3)#加载输入字符串的i索引
blt$t4,48,endLoop不应低于48
bgt$t4,57,不是数字
addi$t4,$t4,-48#获取数字值
bgt$t4,4,oddDigit#>4是两位数的值
lbu$t0,lookupTableOdd($t4)#获取相应的值
addi$t4,$t0,-48#获取数字值
j continueLoop
oddDigit:#这适用于奇数位置的5到9
低于$t4,$t4,5#价值-5
mul$t9,$t4,2乘以2
li$t4,13#基数为13
加上$t4、$t4、$t9#13+系数2
j continueLoop
evenCharLoop:
blt$t4,65,endLoop不应低于65
bgt$t4,122,结束循环#无效字符
addi$t4,
.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
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.