2

すべてはタイトルにあります。いくつかの理由で、私はこのようにしなければなりません。

しかし、コードをコンパイルすると、GCC (または GAS など) に次のエラーが表示されます。

.../Temp/cc1C1fjs.s:19: エラー: 絶対ジャンプでは即値オペランドが不正です

コード:

int main ( int argc, char **argv )
{
    /* Some code */

    ( (void(*)()) &&label)();

    /* Some code */

    return 0;

    label:
    asm ("push %ebp");
    asm ("mov %esp,%ebp");

    /* Some code */
    printf("Hello world");

    asm ("leave");
    asm("ret");
}

ラベルのアドレスをエントリ ポイントとして指定する CreateThread 関数 (私は Windows の下にいます) を使用してスレッドを作成しようとしたため、これが機能するはずであり、完全に機能するはずです。では、コンパイラがこの構文を受け入れるようにするにはどうすればよいでしょうか? または、それを行うための別の方法がありますか?

4

2 に答える 2

0

問題の一部を修正しました:

  1. @aixあなたが正しい、GCCはメイン関数のすべてを削除し、これを次のreturn 0;ように置き換えて修正しました

    asm("leave");
    asm("xor %eax,%eax");
    asm("ret");
    

    これで、ラベルの後のコードが生成されました。

  2. gcc -S file.c次に 実行gcc file.s -o file.exeすると、もちろんエラーが表示され、エラー行に表示されますcall *$L2 (L2は私のcファイルのラベルです)。に置き換えることで機能しcall L2ます。

    これで、ラベルの後のコードとメインの呼び出しの後のコードが実行され、プログラムは状態 0 で適切に終了します。

しかし、コンパイルするたびにそれを行う必要はありません。call *$L2ではなくGCCが書き込むのは正常call L2ですか?

于 2011-03-03T17:07:58.467 に答える
0

解決策はありませんが、いくつかの提案があります。

  1. 実行gcc -S file.cして 19 行目を見て、実際の問題を特定できるかどうかを確認します。
  2. (短い).sファイルの残りの部分を調べて、明らかに問題があるかどうかを確認します。たとえば、私のバージョンの は、その後のすべてがデッド コードであるgccと判断しているように見えるため、コードも実際にアセンブラに到達することもありません。return 0asmprintf
  3. このコードを関数に移動できませんか? このようにして、プロローグ/エピローグを無料で入手できます。住所を取得することもそれほど難しくありません。
于 2011-03-03T14:24:54.183 に答える