【发布时间】:2013-06-07 22:00:29
【问题描述】:
我明白,从内核代码来看,linux系统调用返回类型是long int,大小实际上是32-bit。
是否有可能让一个 linux 系统调用返回一个 64-bit 值(类型为 long long int)?
我知道更改大小没有意义,但我有兴趣了解限制(如果有的话)或者这只是一个偏好问题。
【问题讨论】:
标签: c linux-kernel system-calls
我明白,从内核代码来看,linux系统调用返回类型是long int,大小实际上是32-bit。
是否有可能让一个 linux 系统调用返回一个 64-bit 值(类型为 long long int)?
我知道更改大小没有意义,但我有兴趣了解限制(如果有的话)或者这只是一个偏好问题。
【问题讨论】:
标签: c linux-kernel system-calls
在x86上,返回值放在eax寄存器中,所以不能大于32位;同样,在 x86-64 上,它存储在 rax(eax 的 64 位扩展名)上。
一般来说,趋势似乎是总是使用寄存器作为返回值(这对于系统调用来说似乎是合理的),因此您受限于当前平台的“本机整数”的大小。如果您需要返回更大的内容,则必须通过指针传递输出的位置。
【讨论】:
我在这个答案中将我的讨论限制在 x86_64 和 i386:
系统调用声明为long。
64 位内核会将一个 64 位 int 值返回给用户空间以进行系统调用。 32 位内核将返回 32 位 int 值。
但是,假设在 32 位内核上,您将系统调用的返回类型更改为 long long;然后它们将与 %eax 中的 LSB 和 %edx 中的 MSB 一起在 %eax 和 %edx 中返回
所以你的调用门(entry.S 中的东西)只需要确保它不会在 iret / ret 指令上破坏 %eax 和 %edx 。
您相应的用户空间包装函数通过 int80 或通过旧系统上的 _syscall() 宏进行系统调用,或在新系统中将 syscall(2) 库调用重新实现为 long long 返回类型。
【讨论】: