В книге «Музыкальные приложения микропроцессоров» автор дает следующий алгоритм для 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; \
})