添加2个bcd数字 - mips

时间:2017-12-04 17:09:57

标签: assembly mips bcd

我正在尝试添加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

2 个答案:

答案 0 :(得分:2)

relevant Wikipedia page有一个用于打包BCD的算法:

mkPair

这应该是直接转换为MIPS汇编。

答案 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: