【问题标题】:Return value size or type of a system call in LinuxLinux中系统调用的返回值大小或类型
【发布时间】:2013-06-07 22:00:29
【问题描述】:

我明白,从内核代码来看,linux系统调用返回类型是long int,大小实际上是32-bit

是否有可能让一个 linux 系统调用返回一个 64-bit 值(类型为 long long int)?

我知道更改大小没有意义,但我有兴趣了解限制(如果有的话)或者这只是一个偏好问题。

【问题讨论】:

    标签: c linux-kernel system-calls


    【解决方案1】:

    在x86上,返回值放在eax寄存器中,所以不能大于32位;同样,在 x86-64 上,它存储在 raxeax 的 64 位扩展名)上。

    一般来说,趋势似乎是总是使用寄存器作为返回值(这对于系统调用来说似乎是合理的),因此您受限于当前平台的“本机整数”的大小。如果您需要返回更大的内容,则必须通过指针传递输出的位置。

    【讨论】:

    • 不完全...实际上可以在 32 位架构上返回 long long,您只需稍微处理一下即可。
    • @AhmedMasud:当然是常规调用,但 AFAIK 系统调用调用约定只允许寄存器存储返回类型。
    • 确实如此,但 long long 在 i386(和其他 32 位)平台上由 gcc 以特殊方式处理;结果被转储到寄存器 %eax 和 %edx 或 i386 类型的拱门中;不涉及堆栈,这就是为什么您可以首先拥有具有 long long 返回类型的函数。
    • @AhmedMasud:当然这不是不可能的,只要你有足够的精力,你就可以为所欲为;关键是我 am 在谈论当前用于系统调用的官方 ABI,我认为问题是关于这个的。尽管如此,你的回答还是得到了我的支持,因为你指出了完成这项工作所涉及的变化。
    • 嗯....我刚刚重新阅读了他的问题。那里肯定有歧义,所以我想我们的两个答案都是正确的 +1 给你;)
    【解决方案2】:

    我在这个答案中将我的讨论限制在 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 返回类型。

    【讨论】:

      猜你喜欢
      • 2012-02-11
      • 2014-01-23
      • 2012-08-20
      • 2010-11-06
      • 1970-01-01
      • 2012-03-10
      • 1970-01-01
      • 2021-06-14
      • 2012-10-07
      相关资源
      最近更新 更多