カーネル コードを見ると、Linux システム コールの戻り値の型は long int であり、サイズは実質的に32-bit
.
Linux システム コールが値を返すようにすることは可能ですか64-bit
(たとえば、型のlong long int
)?
サイズを変更しても意味がないことは理解していますが、制限があるかどうか、またはこれが単なる好みの問題であるかどうかを知りたいです。
カーネル コードを見ると、Linux システム コールの戻り値の型は long int であり、サイズは実質的に32-bit
.
Linux システム コールが値を返すようにすることは可能ですか64-bit
(たとえば、型のlong long int
)?
サイズを変更しても意味がないことは理解していますが、制限があるかどうか、またはこれが単なる好みの問題であるかどうかを知りたいです。
x86 では、戻り値はeax
レジスタに格納されるため、32 ビットを超えることはできません。同様に、x86-64 ではrax
(の 64 ビット拡張eax
) に格納されます。
一般に、戻り値に常にレジスタを使用する傾向があるようです (これはシステム コールでは妥当と思われます)。そのため、現在のプラットフォームの「ネイティブ整数」のサイズに制限されます。より大きなものを返す必要がある場合は、ポインターを介して出力の場所を渡す必要があります。
この回答では、議論を x86_64 と i386 に限定しています。
システム コールは として宣言されlong
ます。
64 ビット カーネルは、システム コールのユーザー空間に 64 ビットの int 値を返します。32 ビットのカーネルは、32 ビットの int 値を返します。
ただし、32 ビット カーネルで、システム コールの戻り値の型を long long に変更するとします。次に、%eax と %edx で返され、%eax で LSB と %edx で MSB が返されます。
したがって、コール ゲート (entry.S のもの) は、iret / ret 命令で %eax と %edx を上書きしないようにする必要があります。
古いシステムで int80 または _syscall() マクロを介してシステム呼び出しを行うか、新しいシステムで syscall(2) ライブラリ呼び出しを再実装して long long 戻り値の型にする、対応するユーザー空間ラッパー関数。