2011-05-02 101 views
1

我刚刚开始在AVR-GCC中使用内联汇编程序进行实验。我正在处理一个宏,它将两个8位无符号整数相乘,并将结果存储在一个没有硬件乘法的AVR的16位无符号整数中,以获得比使用标准C函数更高的速度。该代码是:与AVR-GCC内联汇编程序的相对跳转

#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_ */ 

的问题是,我只能用这个宏一次 - 编者不喜欢“增量:”:当宏被插入到做一个乘法被重新定义和“结束”不同的参数集。有没有办法解决?

回答

0

如果定义下面的宏:

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

然后你可以再建线路数量成汇编标签:在AVR GCC内联汇编

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

大,谢谢! – Bitrex 2011-05-02 01:39:01

+0

不幸的是,我注意到了一个问题 - 上面的代码可以将行号插入到标签中,但是如何跳转到该标签?我尝试了这样的:“brcc mult”QUOTE(__ LINE __- 4)“\ n \ t”但它不起作用。也许我只需要使用程序计数器并直接使用偏移量而不是使用标签。 – Bitrex 2011-05-02 04:31:50

+0

@Bitrex:'QUOTE(__ LINE __)'应该解析为'umultfix()'宏被实例化的行号的字符串版本。因此,每次使用时都应该是唯一的。 (显然,如果你在不同的文件中使用宏,你可能也需要使用'(__FILE __)'。) – 2011-05-02 11:14:16

4

其实,你应该

利用特殊图案%=,它被一个独特的nu mber对每个asm声明

如例如在"Cookbook"中所述。

然后你会写是这样的:

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

的“%=”会自动使你的独特标签的一些任意数量的替代。

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