AVR-GCC内联汇编程序的相对跳转

时间:2011-05-02 01:03:46

标签: assembly avr-gcc

我刚刚开始在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 个答案:

答案 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" 
...