2

在 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 程序集,注意我还没有实现负数的功能。该程序运行建议的次数。所以循环不是问题。我认为我的问题可能是我如何计算两个 32 位寄存器之间的右移,目前只是(在伪代码中)

sra 小寄存器 1 如果(大寄存器的最右边位 = 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
4

1 回答 1

0

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

SPARC 组装手册

加法算法

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;
}

乘法算法

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现在替换函数签名)。此外,您可以添加溢出检查并相应地处理错误。

于 2019-11-01T19:30:28.657 回答