我刚刚开始在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:”被重新定义。有没有办法解决这个问题?
答案 0 :(得分:4)
实际上,在AVR gcc内联汇编程序中,你应该
使用特殊模式%= ,在每个asm语句中用唯一数字替换
如上所述,例如"Cookbook"。
然后你会写一些像:
jmp someLabel_%=
...
someLabel_%=:
...
“%=”会自动替换为使您的标签唯一的任意数字。
(注意:使用以数字文字结尾的标签时可能会遇到麻烦:例如myLabel_1%=
和myLabel_12%=
可能会导致冲突。)
答案 1 :(得分:0)
如果您定义以下宏:
#define QUOTE_(x) #x
#define QUOTE(x) QUOTE_(x)
然后,您可以将行号构建到汇编程序标签中:
...
"mult_" QUOTE(__LINE__) ": ror %B0 \n\t"
...