1

我刚刚开始在 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:”。有没有办法解决?

4

2 回答 2

5

实际上,在 AVR gcc 内联汇编程序中,您应该

使用特殊模式%=,在每个 asm 语句中替换为唯一编号

“食谱”中所述。

然后你会写这样的东西:

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

"%=" 会自动替换为使您的标签独一无二的任意数字。

(注意:使用以数字文字结尾的标签时,您可能会遇到麻烦:例如,可能会导致冲突。myLabel_1%=myLabel_12%=

于 2012-05-18T17:34:10.553 回答
0

如果定义以下宏:

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

然后,您可以将行号构建到汇编器标签中:

...
"mult_" QUOTE(__LINE__) ": ror %B0     \n\t" 
...
于 2011-05-02T01:12:11.443 回答