assembly - 在 MIPS 汇编器中实现检查给定的财政代码是否正确

标签 assembly comparison mips

嗯,我有一个作业要做,如下所示:在 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***

最佳答案

第二次编辑:

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

关于assembly - 在 MIPS 汇编器中实现检查给定的财政代码是否正确,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16826844/

相关文章:

assembly - 如何运行 linaro 汇编程序以获取 thumb2 (T32) 指令

c++ - 如何在 Visual Studio 汇编程序输出中分解名称?

performance - vb6 中更快的字符串比较

assembly - 尝试分配变量时,MIPS程序集解析错误

c - 在 MIPS 中扩展或避免 addiu

assembly - 为 X86 编译时如何防止函数对齐到 16 字节边界?

c++ - 在 C++ 中将汇编内联到字节

comparison - Volt 迭代与 Promise 的比较

python - 使用自定义比较的排序键函数

mips - (解析器)语法错误 "array: .word 2,5,3,7,9,(some random numbers)"