относительные скачки с встроенным ассемблером AVR-GCC - PullRequest
1 голос
/ 02 мая 2011

Я только начал экспериментировать с встроенным ассемблером в AVR-GCC.Я работаю над макросом, который умножает два 8-битных целых числа без знака и сохраняет результат в 16-битном целом числе без знака для AVR, которые не имеют аппаратного умножения, для большей скорости, чем при использовании стандартной функции C.Код:

#ifndef UMULTFIX_H_
#define UMULTFIX_H_

#include <inttypes.h>

#define umultfix(a,b)                   \
({                          \
uint16_t product;                   \
uint8_t multiplier = a, multiplicand = b, count = 9;\
asm volatile  (                     \
"mov %A0, %1       \n\t"                    \
"ldi %B0, 0        \n\t"                    \
"clc               \n\t"                    \
"mult: ror %B0     \n\t"                    \
"ror %A0       \n\t"                \
"dec %3        \n\t"                \
"breq end      \n\t"                \
"brcc mult     \n\t"                \
"clc           \n\t"                \
"adc  %B0, %2      \n\t"                    \
"rjmp mult     \n\t"                \
"end:          \n\t"                \
:"=&r" (product): "a" (multiplier), "a" (multiplicand), "a" (count)\
);                          \
product;                        \
})
#endif /* UMULTFIX_H_ */

Проблема в том, что я могу использовать этот макрос только один раз - компилятору не нравятся переопределение «mult:» и «end:» при вставке макроса для умноженияна другой набор аргументов.Есть ли способ обойти это?

Ответы [ 2 ]

4 голосов
/ 18 мая 2012

На самом деле, в встроенном ассемблере gcc AVR вы должны

использовать специальный шаблон % = , который заменяется уникальным числом в каждом операторе asm

, как описано, например, в «Поваренной книге» .

Тогда вы напишите что-то вроде:

jmp someLabel_%=
...
someLabel_%=:
...

"% ="автоматически заменяется каким-либо произвольным числом, которое делает вашу метку уникальной.

(Примечание: вы можете столкнуться с проблемами при использовании меток, заканчивающихся числовыми литералами: myLabel_1%= и myLabel_12%=, например, может вызватьконфликты.)

0 голосов
/ 02 мая 2011

Если вы определите следующие макросы:

#define QUOTE_(x) #x
#define QUOTE(x) QUOTE_(x)

Затем вы можете встроить номер строки в метку ассемблера:

...
"mult_" QUOTE(__LINE__) ": ror %B0     \n\t" 
...
...