Сборка 8x8 алгоритм четырехкратного умножения - PullRequest
7 голосов
/ 14 мая 2011

В книге «Музыкальные приложения микропроцессоров» автор дает следующий алгоритм для умножения 4-х квадрантов двух 8-битных целых чисел со знаком с 16-битным результатом со знаком:

Делает умножение без знака нанеобработанные операнды.Затем, чтобы исправить результат, если знак мультипликатора отрицательный, беззнаковая одинарная точность вычитает множитель из старших 8 битов необработанного 16-битного результата.Если знак множителя также отрицателен, беззнаковая одинарная точность вычитает мультипликатор из верхних 8 бит необработанного 16-битного результата.

Я попытался реализовать это в ассемблере и, похоже, не смог заставить его работать.Например, если я беззнаковый умножить -2 на -2, необработанный результат в двоичном виде будет B11111100.00000100.Когда я вычитаю B1111110 дважды из старших 8 бит в соответствии с алгоритмом, я получаю 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 ]

5 голосов
/ 14 мая 2011

Edit: Вы неправильно вычитаете.

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 голос
/ 14 мая 2011

Когда я дважды вычитаю B1111110 из верхние 8 бит в соответствии с алгоритм, я получаю B11111110.00000100, не B00000000.00000100 как один хочу.

Если дважды вычесть B11111110 из B11111100, я получу B00000000, как требуется:

B11111100 - B11111110 = B11111110
B11111110 - B11111110 = B00000000

Кажется, достаточно просто.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...