2011-05-02 105 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%=,例如,可能會導致衝突)