Pic*_*ana 4 linux assembly return-value nasm system-calls
当我尝试研究内核的系统调用的返回值时,我找到了描述它们的表,以及我需要将它放在不同的寄存器中以使它们工作.但是,我没有找到任何文档说明我从系统调用获得的返回值是什么.我只是在不同的地方找到我收到的东西将在EAX寄存器中.
结果通常在EAX寄存器中返回.
汇编语言循序渐进: Jeff Duntemann 编写的Linux书籍在他的程序中多次说明:
查看sys_read在EAX中的返回值
复制sys_read返回值以便安全保存
我没有解释任何有关此返回值的网站.有没有互联网资源?或者有人能解释我这个价值观吗?
另请参阅这篇关于系统调用的优秀LWN文章,该文章假定具有C知识.
另外:Linux系统调用的权威指南(在x86上)和相关:如果在64位代码中使用32位int 0x80 Linux ABI会发生什么?
C是Unix系统编程的语言,所以所有文档都是用C语言编写的.然后是文档,说明任何给定平台上C接口和asm之间的细微差别,通常在手册页的Notes部分.
sys_read
表示原始系统调用(与libc包装函数相对).read
系统调用的内核实现是一个名为的内核函数sys_read()
.你不能用call
指令调用它,因为它在内核中,而不是库中.但人们仍然在谈论"召唤sys_read
"以区别于libc函数调用.但是,read
即使你的意思是原始系统调用(特别是当libc包装器没有做任何特殊操作时),也可以这样说,就像我在这个答案中所做的那样.
另请注意,syscall.h
定义常量SYS_read
与实际系统调用号一样.(在a int 0x80
或syscall
指令之前放入EAX的值).
Linux系统调用返回值(在x86 中EAX
/ RAX
上)是成功的非负值或负错误代码.例如,-EFAULT
如果您传递无效指针.
syscalls(2)
手册页中记录了此行为.
实际上,-1到-4095意味着错误,其他任何意味着成功.glibc的通用syscall(2)
包装器使用这个序列: cmp rax, -4095
/ jae SYSCALL_ERROR_LABEL
,显然可以保证所有Linux系统调用都具有面向未来的能力.有趣的情况包括mmap
有效地址可以设置符号位,但必须页面对齐,并且getpriority
内核ABI将-20..19返回值范围映射到1..40,并且libc对其进行解码.有关解码系统调用错误返回值的相关答案中的更多详细信息.
更新,是的,对于所有系统调用来说,它肯定是有保证的-4095
..这-1
是Linux运行的所有体系结构上的错误范围.有关更多详细信息,请参阅AOSP非显而易见的syscall()实现.(将来,不同的体系结构可以为MAX_ERRNO使用不同的值,但是像x86-64这样的现有arches的值保证与Linux保持内核ABI稳定的非破坏用户空间策略的一部分相同. )
要查找特定平台的常量的实际数值,您需要找到它们所在的C头文件#define
.有关详细信息,请参阅有关该问题的答案.
每个sys调用的返回值的含义记录在第2节手册页中,如read(2)
.(sys_read
是原始系统调用,glibc read()
函数是一个非常薄的包装器.)大多数手册页都有一个返回值的整个部分.例如
返回值
成功时,返回读取的字节数(零表示文件结束),文件位置按此编号提前.如果此数字小于请求的字节数,则不是错误; 这可能发生在例如因为
现在实际可用的字节数较少(可能是因为我们接近
文件结尾,或者因为我们正在从管道或终端
读取),或者因为read()被中断信号.另见说明.出错时,返回-1,并正确设置errno.在这种情况下,未指定文件位置(如果有)是否
改变.
需要注意的是最后一段描述glibc的包装如何解码值,并设置errno到-EAX
如果原始系统调用的返回值是负的,所以errno=EFAULT
并返回-1
如果原始系统调用返回-EFAULT
.
并且有一个完整的部分列出了read()
允许返回的所有可能的错误代码,以及它们的具体含义read()
.(POSIX标准化了大多数此行为.)
我不确定glibc解码返回值的确切位置mmap(2)
,其中返回值不是有符号类型.它可能使用与通用系统调用包装器相同的方法(检查无符号值> -4096UL
),但每个系统调用的特定包装器没有实际调整寄存器之间的args并调用该函数的开销.
我没有在glibc源代码树中看到它; 据推测,它被埋藏在某些宏层之下.例如在x86-64宏中
归档时间: |
|
查看次数: |
7758 次 |
最近记录: |