_Exit
GCC のインライン アセンブラ機能をいじりながら、C 標準ライブラリに似た、すぐにプロセスを終了する関数を作成しようとしました。
関連するソースコードは次のとおりです。
void immediate_exit(int code)
{
#if defined(__x86_64__)
asm (
//Load exit code into %rdi
"mov %0, %%rdi\n\t"
//Load system call number (group_exit)
"mov $231, %%rax\n\t"
//Linux syscall, 64-bit version.
"syscall\n\t"
//No output operands, single unrestricted input register, no clobbered registers because we're about to exit.
:: "" (code) :
);
//Skip other architectures here, I'll fix these later.
#else
# error "Architecture not supported."
#endif
}
これはデバッグ ビルド (を使用-O0
) では問題なく機能しますが、任意のレベルで最適化をオンにするとすぐに、次のエラーが発生します。
immediate_exit.c: Assembler messages:
immediate_exit.c:4: Error: unsupported for `mov'
そこで、両方のビルドのアセンブラー出力を調べました (.cfi*
わかりやすくするために、ディレクティブやその他のものを削除しました。問題がある場合は、再度追加できます)。デバッグ ビルド:
immediate_exit:
.LFB0:
pushq %rbp
movq %rsp, %rbp
movl %edi, -4(%rbp)
mov -4(%rbp), %rdi
mov $231, %rax
syscall
popq %rbp
ret
そして最適化されたバージョン:
immediate_exit:
.LFB0:
mov %edi, %rdi
mov $231, %rax
syscall
ret
そのため、最適化されたバージョンは、32 ビット レジスタをからロードするのではなくedi
、64ビット レジスタに入れようとしています。これがエラーの原因であると推測されます。rdi
rbp
これで、 'm' を のレジスタ制約として指定することでこれを修正できます。これにより、最適化レベルに関係なくcode
GCC がロードされます。rbp
ただし、コンパイラとその作成者は、どこに何かを配置するかについて、私よりもはるかに優れた考えを持っていると思うので、私はそれをしたくありません。
だから(最後に!)私の質問は、GCCをアセンブリ出力でrdi
はなく使用するように説得するにはどうすればよいですか?edi