2017-02-07 3 views
0

gccを使用していくつかのC関数をコンパイルしようとしていますが、どのレジスタでも実行できません。私はx86_64に取り組んでいます。 私はno_caller_saved_registersを使用しようとしていますが、私が得るすべてはこれです:GCC、no_caller_saved_registers属性を使用して

警告:「no_caller_saved_registers」属性ディレクティブを無視[-Wattributes]

のボイドのfoo()属性((no_caller_saved_registers));

私の暫定的な解決策は、すべてのレジスタを保存して復元するために、インラインアセンブリのプロローグとエピローグを書くことでしたが、実際にはその属性を機能させることをお勧めします。

誰でもこの問題がありますか?

+0

実際に何をしようとしているのか説明できますか?私は合理的には、gccに関数内のレジスタを使わないように強制することはできません - 確かに何も複雑ではありません。なぜなら、x86のほとんどの命令は、少なくとも1つのオペランドをレジスタにする必要があるからです。 –

+1

私はこれらの関数を呼び出すために、アセンブリコードをインストルメントしています。私はそれらを復元する限り、どのレジスタを使っても問題ありません。 – user1637056

+0

私はこのコンパイルフラグを見つけました。これは、私が望む影響がありますが、ファイル全体には-fcall-saved-regです。それはいくつかのレジスタ(rax、rdx)で正しく動作しません – user1637056

答えて

0

No_caller_saved_registersはin June 2016しか実装されていないので、公式のGCCリリースatmでは利用できません。

+0

ありがとうございました!!! – user1637056

+0

更新:この属性はgcc 7.2でサポートされています。このコンパイルフラグを追加する必要があります: gcc-7 main.c -general-regs-only – user1637056

0

これは、ページフォルトハンドラの一種であるため、ANYレジスタを壊さない関数が必要です。 ここでの前回の回答により、この属性は将来のgccリリースでサポートされる予定ですが、まだ主流ではありません。私は任意のレジスタ値を壊してはならないページフォルトハンドラのいくつかの並べ替えとして使用することを、この属性がなければ

、私の機能は、次のようになります。

#define PREFIX_SIZE (14l) 
__asm__ volatile ("in: \n\t" 
        "pushf\n\t" 
        "push %rbp\n\t" 
        "mov %rsp,%rbp\n\t" 
        "push %rdi\n\t" 
        "push %rsi\n\t" 
        "push %rdx\n\t" 
        "push %rcx\n\t" 
        "push %r8 \n\t" 
        "push %r9 \n\t" 
        "push %rax\n\t" 
       ); 

void page_fault_handler() { 
    /* 
    * some code here 
    */ 
    __asm__ volatile ("jmp reg_out\n\t"); 
} 

__asm__ volatile ("reg_out: \n\t" 
        "leave\n\t" // what the original code was doing 
        "pop %rax\n\t" 
        "pop %r9 \n\t" 
        "pop %r8 \n\t" 
        "pop %rcx\n\t" 
        "pop %rdx\n\t" 
        "pop %rsi\n\t" 
        "pop %rdi\n\t" 
        "leave\n\t" // my leave 
        "popf\n\t" 
        "ret\n\t"); 

私はこれを呼び出す必要がありますので、それは明らかに迷惑です住所:

(void*)((ulong)page_fault_handler - PREFIX_SIZE) 

の代わりに、それはまたPRを引き起こし

(void*)page_fault_handler 

obolmsは-O2最適化フラグを付けてコンパイルすると、ラベルの順序を変更するためです。

あなたが注意している場合私はこのコードをコンパイルしたので、私は、ここに手動でRBX保存されません。

gcc -fcall-saved-rbx 

をこのコンパイルフラグは、関数の始まりと終わりにRBXを保存して復元するようにコンパイラーに指示します。 なぜ私はすべてのレジスターでそれをやっていないのですか? raxの内部コンパイラエラーが発生するため:https://gcc.gnu.org/bugzilla/show_bug.cgi?id=79407

関連する問題