これは、ページフォルトハンドラの一種であるため、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
実際に何をしようとしているのか説明できますか?私は合理的には、gccに関数内のレジスタを使わないように強制することはできません - 確かに何も複雑ではありません。なぜなら、x86のほとんどの命令は、少なくとも1つのオペランドをレジスタにする必要があるからです。 –
私はこれらの関数を呼び出すために、アセンブリコードをインストルメントしています。私はそれらを復元する限り、どのレジスタを使っても問題ありません。 – user1637056
私はこのコンパイルフラグを見つけました。これは、私が望む影響がありますが、ファイル全体には-fcall-saved-regです。それはいくつかのレジスタ(rax、rdx)で正しく動作しません – user1637056