添加 2 个 bcd 数字-mips

Adding 2 bcd numbers-mips

我正在尝试将存储在 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

relevant Wikipedia page有一个压缩BCD加法算法:

uint32_t BCDadd(uint32_t a,uint32_t b)
{
    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
    return t1 - t2;                // corrected BCD sum
}

这应该可以直接转化为 MIPS 程序集。

根据@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: