我正在尝试添加2个存储在2个寄存器中的数字。每个号码都是bcd格式,有8位数字。 我想知道我是否有更好的方法,然后一次只能每4位工作一次。
这就是我的开始:
.text
main:
addi $s2,$zero,00010010001101000101011001111000#num1
addi $s3,$zero,00010100011110000101001000110110#num2
addi $t0,$zero,00000000000000000000000000001111#mask
and $t1,$t0,$s2#geting digit#1 of num1
and $t2,$t0,$s3#geting digit#2 of num2
add $t3,$t1,$t2#adding digits
#checking for overflow
#doing the same for the rest of the digits
#add $s4,$s3,$s2
答案 0 :(得分:2)
答案 1 :(得分:0)
基于@harold的答案和@ Ped7g的帮助我已经用mips编写了BCD添加算法。 我添加了一段代码来检查是否有溢出并处理它。 现在它适用于所有情况。
#Description: program to sum 2 numbers in BCD format.
#The numbers must be in $s2, $s3.
#The answer will appear in $s4. If we have overflow $s5 = 1 else $s5=0;
#The program in c:
#Based on an algorithm to calculate an unsigned 8-digit packed BCD add using 32-bit binary operations.
# uint32_t t1, t2; // unsigned 32-bit intermediate values
# t1 = a + 0x06666666;
# t2 = t1 ^ b; // sum without carry propagation
# t1 = t1 + b; // provisional sum
# t2 = t1 ^ t2; // all the binary carry bits
# t2 = ~t2 & 0x11111110; // just the BCD carry bits
# t2 = (t2 >> 2) | (t2 >> 3); // correction
# uint32_t sum = t1 - t2; // corrected BCD sum
# uint32_t overflow = (!sum.top_digit.isValid) || (sum < a);
# //if we have overflow it means that the MSB is not in valid formt.
# sum = (overflow == 1 ? sum - 0xA0000000 : sum); in this case we must sub 0xA from MSB
.text
main:
#assigning 2 numbers in bcd format to add them up
addi $s2,$zero,0x56251894
addi $s3,$zero,0x99649449
addi $t1,$s2,0x06666666 #t1 = a + 0x06666666;
xor $t2,$t1,$s3 #t2 = t1 ^ b; // sum without carry propagation
addu $t1,$t1,$s3 #t1 = t1 + b; // provisional sum
xor $t2,$t1,$t2 #t2 = t1 ^ t2; // all the binary carry bits
add $t3,$zero,-1 #load -1 into help-register
xor $t2, $t2,$t3 #actual not-operation
add $t4,$zero,0x11111110#loading 0x11111110 into help-register
and $t2,$t2,$t4 #t2 = ~t2 & 0x11111110;//just the BCD carry bits
add $t3,$zero,$zero #reseting $t3
add $t4,$zero,$zero #reseting $t4
srl $t3,$t2,2 #(t2 >> 2)
srl $t4,$t2,3 #(t2 >> 3)
or $t2,$t3,$t4 #(t2 >> 2) | (t2 >> 3)
sub $s4,$t1,$t2 #t2 = (t2 >> 2) | (t2 >> 3)// correction
add $t1,$zero,$zero #reseting $t1
add $t2,$zero,0xA0000000#load 0xA0000000 into help-register
sltu $t1,$s4,$t2
# checking if a>0x50000000 && $s4<0x40000000
#This is to make sure that if MSB>f then we can control it(We will use slt instead of sltu on ).
add $t5,$zero,0x50000000#load 0x50000000 into help-register
sltu $t6,$s2,$t5
bnez $t6,isValid #checking if a>0x50000000
add $t5,$zero,0x40000000#load 0x40000000 into help-register
sltu $t6,$s4,$t5
beqz $t6,isValid #checking if $s4<0x40000000
# if a>0x50000000 && $s4<0x40000000
addi $t2,$zero,0xA0000000#load 0xA0000000 into help-register
slt $t1,$s4,$t2
isValid:
#this is to check if top digit is valid
add $t2,$zero,1 #load 1 into help-register
xor $t1,$t1,$t2 #actual not-operation
or $s5,$t1,$zero #overflow = (!sum.top_digit.isValid) || (sum < a);
#Checking if MSB is valid if not we need to sub 1001 from this bit(MSB bit).
beq $s5,$zero,end #Checking if we don't have overflow
subiu $s4,$s4,0xA0000000#if we have ofverflow we need to sub 10 from the MSB.
end: