装配8x8四象限乘法算法

时间:2011-05-14 09:04:36

标签: math binary assembly

在“微处理器的音乐应用”一书中,作者给出了以下算法,用两位8位有符号整数和16位有符号结果进行4象限乘法运算:

对原始操作数执行无符号乘法运算。然后为了校正结果,如果被乘数符号为负,则无符号单精度从原始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;                   \
    })

2 个答案:

答案 0 :(得分:5)

编辑: 你的减法是错误的。

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

答案 1 :(得分:1)

  

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

如果我从B11111110两次减去B11111100,我会根据需要获得B00000000

B11111100 - B11111110 = B11111110
B11111110 - B11111110 = B00000000

看起来很简单。