4

インラインアセンブラにいくつかの値を特定のレジスタにコピーさせようとしていますが、文句を言うだけです。これは、エラーをトリガーするコードの短いバージョンです。

asm("" :: "r0" (value));
asm("" :: "a1" (value));

両方の行がトリガーされます:

Error: matching constraint references invalid operand number

では、直接取得するレジスタを指定するにはどうすればよいですか?値の名前を導入して自分でコピーできることはわかっていますが、このコードは短くて読みやすいため、これは避けたいと思います。

なぜ私が尋ねているのか 現在、私はいくつかのシステムコールに取り組んでいます。次のようなシステムコールマクロを使用したい:

#define SYSCALL0(NUMBER) asm("swi #" STRINGIFY(NUMBER));
#define SYSCALL1(NUMBER, A) asm("swi #" STRINGIFY(NUMBER) :: "r0"(A));
#define SYSCALL2(NUMBER, A, B) asm("swi #" STRINGIFY(NUMBER) :: "r0"(A), "r1"(B));
...

ご覧のとおり、これはオンラインにうまく収まります。もちろん、私は次のようなことをすることができます:

#define SYSCALL1(NUMBER, A) register type R0 asm("r0") = A;
                            SYSCALL0(NUMBER)

しかし、その後、型エラーが発生しないように、またはさまざまな関数でマクロを使用するたびに正しく与えるために、に変換Aする必要があります。typetype

4

1 に答える 1

2

GCCには、ショートカットがあります。

register long r0 asm ("r0");

次にr0、そのレジスタを「エイリアス」します。

それをステートメント式と組み合わせるとr0、「戻り値」として取得することもできます。

#define SYSCALL1(NUMBER,A) ({\
  register long r0 asm("r0") = (long) (A); \
  asm("swi #" STRINGIFY(NUMBER) : "=r"(r0) : "r"(r0) : "memory"); \
  r0; })

(クローバーが正当であるかどうかはわかりませんが、uClibcシステムコールの実装にはそれがあります。)

拡張アセンブリおよびローカル登録変数を参照してください。

于 2012-05-31T10:30:40.800 に答える