开发者

relative jumps with AVR-GCC inline assembler

I've just started experimenting with inline assembler in AVR-GCC. I'm working on a macro that multiplies two 8 bit unsigned integers and stores the result in a 16 bit unsigned integer for AVRs that don't have a hardware multiply, for greater speed than using the standard C function. The code is:

#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_ 开发者_Go百科*/

The problem is I can only use this macro once - the complier doesn't like "mult:" and "end:" being redefined when the macro is inserted to do a multiplication on a different set of arguments. Is there any way around this?


Actually, in AVR gcc inline assembler, you should

make use of the special pattern %=, which is replaced by a unique number on each asm statement

as described, e.g., in the "Cookbook".

Then you would write something like:

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

The "%=" is automatically replaced by some arbitrary number which makes your label unique.

(Note: You may be heading for trouble when using labels ending in numeric literals: myLabel_1%= and myLabel_12%=, for instance, may cause conflicts.)


If you define the following macros:

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

Then you can then build the line-number into the assembler label:

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

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜