1

AVR-GCCでインラインアセンブラの実験を始めたところです。標準のC関数を使用するよりも高速で、2つの8ビット符号なし整数を乗算し、その結果をハードウェア乗算を持たないAVRの16ビット符号なし整数に格納するマクロに取り組んでいます。コードは次のとおりです。

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

問題は、このマクロを1回しか使用できないことです。コンパイラーは、マクロが挿入されて別の引数のセットで乗算を行うときに、「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 に答える