汇编8x8四象限乘法算法

发布于 2024-11-07 16:40:33 字数 1197 浏览 6 评论 0原文

在《微处理器的音乐应用》一书中,作者给出了以下算法,用于对两个 8 位有符号整数进行 4 象限乘法,得到 16 位有符号结果:

对原始操作数进行无符号乘法。然后为了纠正结果,如果被乘数符号为负,则无符号单精度从原始 16 位结果的前 8 位中减去乘数。如果乘数符号也为负,则无符号单精度从原始 16 位结果的高 8 位中减去被乘数。

我尝试在汇编程序中实现它,但似乎无法让它工作。例如,如果我无符号乘法 -2 乘以 -2,则二进制的原始结果为 B11111100.00000100。当我根据算法从前 8 位减去 B1111110 两次时,我得到 B11111110.00000100,而不是人们想要的 B00000000.00000100。感谢您对我可能出错的地方的任何见解!

编辑-代码:

    #define smultfix(a,b)       \
    ({                      \
    int16_t sproduct;               \
    int8_t smultiplier = a, smultiplicand = b;  \
    uint16_t uproduct = umultfix(smultiplier,smultiplicand);\
    asm volatile (                  \
    "add %2, r1 \n\t"               \
    "brpl smult_"QUOTE(__LINE__)"\n\t"      \
    "sec                 \n\t"      \
    "sbc  %B3, %1            \n\t"      \
    "smult_"QUOTE(__LINE__)": add %1, r1 \n\t"  \
    "brpl send_"QUOTE(__LINE__)"  \n\t"     \
    "sec                 \n\t"      \
    "sbc  %B3, %2            \n\t"      \
    "send_"QUOTE(__LINE__)": movw %A0,%A3 \n\t" \
    :"=&r" (sproduct):"a" (smultiplier), "a" (smultiplicand), "a" (uproduct)\
    );                      \
    sproduct;                   \
    })

In the book "Musical Applications of Microprocessors," the author gives the following algorithm to do a 4 quadrant multiplication of two 8 bit signed integers with a 16 bit signed result:

Do an unsigned multiply on the raw operands. Then to correct the result, if the multiplicand sign is negative, unsigned single precision subtract the multiplier from the top 8 bits of the raw 16 bit result. If the multiplier sign is also negative, unsigned single precision subtract the multiplicand from the top 8 bits of the raw 16 bit result.

I tried implementing this in assembler and can't seem to get it to work. For example, if I unsigned multiply -2 times -2 the raw result in binary is B11111100.00000100. When I subtract B1111110 twice from the top 8 bits according to the algorithm, I get B11111110.00000100, not B00000000.00000100 as one would want. Thanks for any insight into where I might be going wrong!

Edit - code:

    #define smultfix(a,b)       \
    ({                      \
    int16_t sproduct;               \
    int8_t smultiplier = a, smultiplicand = b;  \
    uint16_t uproduct = umultfix(smultiplier,smultiplicand);\
    asm volatile (                  \
    "add %2, r1 \n\t"               \
    "brpl smult_"QUOTE(__LINE__)"\n\t"      \
    "sec                 \n\t"      \
    "sbc  %B3, %1            \n\t"      \
    "smult_"QUOTE(__LINE__)": add %1, r1 \n\t"  \
    "brpl send_"QUOTE(__LINE__)"  \n\t"     \
    "sec                 \n\t"      \
    "sbc  %B3, %2            \n\t"      \
    "send_"QUOTE(__LINE__)": movw %A0,%A3 \n\t" \
    :"=&r" (sproduct):"a" (smultiplier), "a" (smultiplicand), "a" (uproduct)\
    );                      \
    sproduct;                   \
    })

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

淡淡绿茶香 2024-11-14 16:40:33

编辑:
你减法错了。

1111'1110b * 1111'1110b == 1111'1100'0000'0100b
                          -1111'1110'0000'0000b                   
                          -1111'1110'0000'0000b  
                          ---------------------
                                           100b  

否则你的算法是正确的:在第四象限,你需要减去 100h 乘以总和 (a+b)。将两个补码字节写为 (100h-x) 我得到:

(100h-a)(100h-b) = 10000h - 100h*(a+b) + ab = 100h*(100h-a) + 100h*(100h-b) + ab mod 10000h
(100h-a)(100h-b) - 100h*(100h-a) - 100*(100h-b) = ab mod 10000h

Edit:
You got the subtraction wrong.

1111'1110b * 1111'1110b == 1111'1100'0000'0100b
                          -1111'1110'0000'0000b                   
                          -1111'1110'0000'0000b  
                          ---------------------
                                           100b  

Otherwise your algorithm is correct: In the fourth quadrant, you need to subtract 100h multiplied with the sum (a+b). Writing the two-complement bytes as (100h-x) I get:

(100h-a)(100h-b) = 10000h - 100h*(a+b) + ab = 100h*(100h-a) + 100h*(100h-b) + ab mod 10000h
(100h-a)(100h-b) - 100h*(100h-a) - 100*(100h-b) = ab mod 10000h
迎风吟唱 2024-11-14 16:40:33

当我减去 B1111110 两次时
前 8 位根据
算法,我得到 B11111110.00000100,
不是 B00000000.00000100 那样
想要。

如果我从 B11111100 中减去 B11111110 两次,我会根据要求得到 B00000000

B11111100 - B11111110 = B11111110
B11111110 - B11111110 = B00000000

看起来很简单。

When I subtract B1111110 twice from
the top 8 bits according to the
algorithm, I get B11111110.00000100,
not B00000000.00000100 as one would
want.

If I subtract B11111110 twice from B11111100, I get B00000000, as required:

B11111100 - B11111110 = B11111110
B11111110 - B11111110 = B00000000

Seems simple enough.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文