1

C アセンブリとインライン アセンブリ間での引数の受け渡しについて質問があります

配列をインライン アセンブリに渡すのに問題があります。「エラー: メモリ入力 1 は直接アドレス指定できません」というエラーが表示され続けます

これが私のコードの例です:

void main()
{
    char name[] = "thisisatest";
        __asm__ ("\
        .intel_syntax noprefix     \n\
        mov eax, %[name]           \n\
        inc (eax)                  \n\
       "
    :/*no output*/
    :[name]"m"(name)
    );
}

これにより、文字列の最初の文字がインクリメントされます (「u」になります) が、ビルドされません。

アイデア?

4

3 に答える 3

4

他の誰かがこれに出くわした場合に備えて、私はそれを機能させました。

void main()
{
    char name[] = "thisisatest";
        __asm__ ("\
        .intel_syntax noprefix     \n\
        lea, eax, %[name]          \n\
        inc BYTE PTR [eax]          \n\
       "
    :/*no output*/
    :[name]"m"(name[0])
    );
}

キーは、配列の最初の要素をメモリ パラメータとして渡し、実効アドレスを要求していました。次に、文字列へのポインターがありました。これが他の人に役立つことを願っています

于 2013-10-29T13:13:31.357 に答える
2

配列はポインターに変換されるため、配列をインライン アセンブリ (構造体に含まれている場合を除く) に渡すことはできません。また、そのポインターは左辺値ではないため、メモリ制約を適用することもできません。

配列の要素を次のように渡すことができます。

asm ("incb %0" : "+g" name[0] : : ); // AT&T syntax

または、アドレス:

asm volatile ("incb (%0)" : : "r" name : "memory"); // AT&T syntax

また、インライン アセンブラでアセンブラ構文を切り替える場合は、後で復元する必要があります。メモリ asm オペランドは使用しないでください。これらは間違った構文になるためです。

編集: 2 番目のコード フラグメントの変数名を省略し、最初のコード フラグメントにブラケットを追加しました。

于 2013-10-19T08:00:38.147 に答える
0

&name は実行しないでください。名前だけを試してください。配列は常に、それが配置されているメモリ内のスペースを指します。今あなたがやろうとしているのは、配列 'thisisatest' を、それほど多くのデータを保持できないレジスター (eax) に入れることです。

レジスターは、数文字 (レジスターのサイズに応じて) または配列が配置されている場所のアドレスのいずれかを保持できます。

于 2013-10-18T17:58:43.720 に答える