6

ポインターを eax にプッシュし、別のポインターを ebx レジスターにプッシュする必要があります。私は最初にこれを解決しました:

register int eax asm("eax");
register int ebx asm("ebx");
int main()
{
     eax = ptr1;
     ebx = ptr2;
}

これは魅力のように機能しました。しかし、これを他のコードに追加すると、コードのまったく無関係な部分で、gcc がクラス AREG にスピルするレジスタを見つけられないという奇妙なエラーが発生しました。ググったところ、実際にはgccのバグであることが判明しました-.-。したがって、2 つのポインターを eax および ebx レジスターにプッシュする別の方法が必要です。誰でもアイデアはありますか?

編集:

ここで私が何を達成しようとしているのかと人々から尋ねられたので、少し説明したいと思います。

プログラムで実行しようとしているアセンブリ コードの eax と ebx を変更する必要があります。このアセンブリ コードを実行し、eax および ebx レジスタを介してパラメーターへのポインターを与える必要があります。ebx でアセンブリ コードへのポインターをプッシュし、ebx を呼び出して、アセンブリ コードを実行します。レジスターをグローバルではなくローカルで呼び出すと、アセンブリ コードがクラッシュします。グローバルに呼び出すと、ランダム関数の最後でこの奇妙なエラーが発生します。その関数を削除すると、別のランダム関数で同じエラーがスローされます。関数がなくなるまでは機能しますが、残りのコードが恋しいです:P

4

2 に答える 2

6

EAX/に特定のパラメーターを必要とする (インライン) アセンブリ コードがある場合EBX、gcc でこれを行う方法は次のとおりです。

__asm__("transmogrify %0, %1\n" : "+a"(val_for_eax), "+b"(val_for_ebx));

これは、gcc がインライン アセンブリ制約を呼び出すものを使用します。これは、アセンブリ コード (それが何であれ) がval_for_eax/val_for_ebxEAX/ EBX( a/のb部分) を期待していること、およびこれらの変数の潜在的に変更されたバージョン (それは+)を返すことをコンパイラに伝えます。も登録します。

それを超えて、ステートメント内の実際のコードasm()はコンパイラーにとって重要ではありません-パラメーター%0%1ライブの場所を知る必要がある/知りたいだけです。上記の例は、transmogrify現在の x86 命令セットに命令が存在しないため、アセンブラーの実行時に失敗します。有効なものに置き換えるだけです。

gcc がこのように動作する理由と、正確に何を行うように指示できるかについての説明は、次の GCC マニュアルにあります。

変数に特定のレジスタを指定できますが、gcc の動作方法 / gcc でのインライン アセンブリの実装方法により、指定しても(!) gcc が使用するためにレジスタが予約されている(範囲外)という意味ではありません。独自の目的のために。これは、特定の単一ブロックの制約によってのみ達成できます。制約は、実際のアセンブリ コードを配置する前にそれらのレジスタに何を書き込むか、および後でそれらから何を読み取るかを gcc に指示します。asm()

于 2013-05-26T07:43:32.437 に答える