SPARC中的乘法算法

时间:2012-10-13 20:00:26

标签: assembly multiplication sparc

在SPARC中的这个乘法算法上工作了几天(直接)......真的无法弄清楚出了什么问题。我已经完成了代码的几次迭代。它正在做拟议的C算法想要它。这是在C

negative = multiplier >= 0 ? 0 : 1;
product = 0;
for (i = 0; i < 32; i++) {
    if (multiplier & 1)
        product += multiplicand;
(product and multiplier registers combined as a unit) >> 1;
}
if (negative)
    product -= multiplicand;

这里是SPARC Assembly,注意我还没有实现负数的功能。该程序运行建议的次数。所以循环不是问题。我想我的问题可能是我如何考虑两个32位寄存器的正确移位,目前只是(在Psuedo代码中)

sra small register 1 if(大寄存器的最右边= 1)      将最小位的小寄存器更改为1 sra更大的注册

但它似乎并没有按计划进行,因为我的数字确实很糟糕

这是SPARC中的整个程序......你们提供的任何帮助都将受到赞赏。

 fmt:   .asciz "Multiplicand: %d, Product: %8.8X%8.8X Counter: %d\n"            !output statement
.align 4                !align formatting

.global main
main:   save     %sp, -96, %sp
set     82732983, %l0       !move multiplicand into register %l0
set     120490892, %l1      !move multiplier into register %l1
set     0, %l2          !initialize product variable at 0
set     1, %l3          !initialize counter variable to 1
ba  test
mov     32, %l5         !put max loop value in a register

loop:
set     fmt, %o0        !setup the format string for the print statement
mov     %l0, %o1        !moving variables for printing
mov     %l1, %o2
mov     %l2, %o3
mov %l3, %o4
call    printf
nop
postprint:
    and     %l1, 1, %l6     !bitwise and between multiplier and 1, store result in %l6
cmp     %l6, 0          !comparison statement comparing the above to 1
be  else            !skip the addition if rightmost bit of multiplier is 0
nop

add     %l0, %l2, %l2       !adding multiplicand and product
sra     %l1, 1, %l1     !shifting multiplier right
and     1, %l2, %l6     !checking if rightmost bit of product is a 1
cmp     %l6, 1          !conditional statement to check this
bl  endif           !if it's not a one, branch to zero
nop             !non op

clr     %o4
set 0x40000000, %o4     !put 0x40000000 in a register
or      %l1,    %o4,    %l1 !if it is a one, bitwise do or with 0x40000000 to make a one in the leftmost bit of the multiplier
    sra     %l2,    1,  %l2     !shift product to the right by 1
    inc     %l3         !increment counter variable
    ba      test            !and branch to the testing statement
    nop

endif:
clr     %o5
sra     %l2, 1, %l2     !arithmetic shift product right by one (first line of endif)
inc     %l3         !increment counter variable
ba  test            
nop
else:
    sra     %l1, 1, %l1     !shift multiplier to the right
    and     %l2, 1, %l6     !check if rightmost bit of product is 1
    cmp     %l6, 1          !conditional statement to check this
    bl      endif           !branch to endif if it's not
    nop             !nop
clr     %o4
set 0x40000000, %o4     !put 0x40000000 in a register
    or      %l1, %o4, %l1       !if the rightmost bit is one, we use a bitwise or to place a 1 in the leftmost bit of the multiplier
    sra     %l2, 1, %l2     !then right arithmetic shift the product
    inc     %l3         !and increment the counter
    ba      test
    nop

test:   cmp     %l3, %l5
    bl      loop


done:   mov 1,  %g1             !Exit the program
    ta  0

1 个答案:

答案 0 :(得分:0)

将功能拆分为:Add()Multiply()

SPARC Assembly manual

Addition Algorithm

unsigned int Add(unsigned int num1, unsigned int num2)
{
    /* Iterate till there is no carry  */
    while (num2 != 0)
    {
        /* carry now contains common set bits of num1 and num2  */
        unsigned int carry = num1 & num2;  

        /* Sum of bits of numbers where at least one of the bits is not set */
        num1 = num1 ^ num2; 

        /* Carry is shifted by one so that adding it to x gives the required sum */
        num2 = carry << 1;
    }
    return num1;
}

Multiplication Algorithm

unsigned int Multiply(unsigned int multiplicand, unsigned int multiplier)
{
    unsigned int result = 0;

    while(multiplier != 0) /* Use while instead of for */
    {
        if (multiplier & 0x01) 
        {
            result = Add(result, multiplicand);
        }

        multiplicand <<= 1; /* Left shifting the value contained in 'multiplicand' by 1 */
        multiplier >>=1;    /* Right shifting the value contained in 'multiplier' by 1. */
   }

   return result;
}

请注意:此处假设int是32位整数。 (您可以根据当前的typedefs替换功能签名)。另外,您可以添加溢出检查并相应地处理错误。