我有一个分配这样做:在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***
答案 0 :(得分: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
答案 1 :(得分: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.