我正在阅读 Linux Kernel Development ,第3版,以了解内核实现和设计。第5章是关于系统调用的。作者展示了使用SYSCALL_DEFINE0
宏定义的系统调用声明的示例,该宏在该特定示例中扩展为:
asmlinkage long sys_getpid(void)
他进一步说:
[...]对于32位和64位系统之间的兼容性,定义为在用户空间中返回int的系统调用在内核中返回long。
他没有比这更深入,我不能完全理解为什么会这样。为什么使用long
与32位和64位系统相关?为什么我们不能返回普通int
?
答案 0 :(得分:11)
因为许多64 bits计算机(例如x86-64)用于公共GCC编译器sizeof(int)==4
但sizeof(void*)==8 && sizeof(long)==8
;这称为I32LP64(或仅LP64)data model
例如,在Linux / x86-64系统上编译并运行以下程序:
#include<stdio.h>
#include<stdint.h>
int main ()
{
printf ("sizeof(int)=%d\n", (int) sizeof (int));
printf ("sizeof(intptr_t)=%d\n", (int) sizeof (intptr_t));
printf ("sizeof(short)=%d\n", (int) sizeof (short));
printf ("sizeof(long)=%d\n", (int) sizeof (long));
printf ("sizeof(long long)=%d\n", (int) sizeof (long long));
printf ("sizeof(void*)=%d\n", (int) sizeof (void *));
return 0;
}
使用gcc -Wall s.c -o s
在我的系统上进行编译并在我的Debian / Sid / x86-64(i3770k处理器GCC 4.8处理器when Linus上运行./s
。
sizeof(int)=4
sizeof(intptr_t)=8
sizeof(short)=2
sizeof(long)=8
sizeof(long long)=8
sizeof(void*)=8
在使用gcc -m32 -Wall s.c -o s32
并运行./s32
sizeof(int)=4
sizeof(intptr_t)=4
sizeof(short)=2
sizeof(long)=4
sizeof(long long)=8
sizeof(void*)=4
如果使用gcc -mx32 -O3 -Wall s.c -o sx32
编译x32,我得到相同的输出!
intptr_t
....我不知道(可能是习惯问题; C99首先开始编写他的内核,{{3标准 - 定义<stdint.h>
和intptr_t
- 尚不存在。)
详细了解ABIs,特别请仔细阅读X86-64 ABI(另请参阅x32 ABI ...)和x86 calling conventions上的wikipage。