Assembly中系统调用的返回值是多少? [英] What are the return values of system calls in Assembly?

查看:95
本文介绍了Assembly中系统调用的返回值是多少?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当我尝试研究内核的系统调用的返回值时,我会找到描述它们的表,以及需要放入不同的寄存器中以使其起作用的表.但是,我找不到任何文档说明它从系统调用中得到的什么.我只是在不同的地方发现我收到的东西将在EAX寄存器中.

When I try to research about return values of system calls of the kernel, I find tables that describe them and what do I need to put in the different registers to let them work. However, I don't find any documentation where it states what is that return value I get from the system call. I'm just finding in different places that what I receive will be in the EAX register.

TutorialsPoint :

结果通常在EAX寄存器中返回.

The result is usually returned in the EAX register.

杰夫·邓特曼(Jeff Duntemann)的

汇编语言循序渐进:使用Linux编程一书在其程序中多次陈述:

Assembly Language Step-By-Step: Programming with Linux book by Jeff Duntemann states many times in his programs:

  • 查看EAX中sys_read的返回值

  • Look at sys_read's return value in EAX

复制sys_read返回值以安全保存


我没有解释有关此返回值的任何网站.有互联网资源吗?还是有人可以向我解释一下这些价值观?


Any of the websites I have don't explain about this return value. Is there any Internet source? Or can someone explain me about this values?

推荐答案

另请参见这篇关于系统的出色的LWN文章调用,它假定您具有C知识.

See also this excellent LWN article about system calls which assumes C knowledge.

也: 《 Linux系统调用的权威指南》(在x86上),并与之相关: C是Unix系统编程的语言,因此所有文档都以C表示.然后,在任何给定平台上,都有C接口和asm之间的细微差别的文档,通常在手册页的Notes部分中

C is the language of Unix systems programming, so all the documentation is in terms of C. And then there's documentation for the minor differences between the C interface and the asm on any given platform, usually in the Notes section of man pages.

sys_read表示原始系统调用(与libc包装器函数相对). read系统调用的内核实现是称为sys_read()的内核函数.您不能使用call指令来调用它,因为它在内核中,而不是库中.但是人们仍然在谈论调用sys_read"以将其与libc函数调用区分开.但是,即使您的意思是原始系统调用(特别是当libc包装器没有做任何特殊的事情时),也可以说read,就像我在此答案中所做的那样.

sys_read means the raw system call (as opposed to the libc wrapper function). The kernel implementation of the read system call is a kernel function called sys_read(). You can't call it with a call instruction, because it's in the kernel, not a library. But people still talk about "calling sys_read" to distinguish it from the libc function call. However, it's ok to say read even when you mean the raw system call (especially when the libc wrapper doesn't do anything special), like I do in this answer.

还请注意,syscall.h使用实际的系统调用号定义了像SYS_read这样的常量. (您在EAX中的int 0x80syscall指令之前输入的值).

Also note that syscall.h defines constants like SYS_read with the actual system call number. (The value you put in EAX before an int 0x80 or syscall instruction).

Linux系统调用返回值(在x86上的EAX/RAX中)是非负值,或者是

Linux system call return values (in EAX/RAX on x86) are either a non-negative value for success, or a negative error code. e.g. -EFAULT if you pass an invalid pointer.

syscalls(2) 中记录了此行为.手册页.

This behaviour is documented in the syscalls(2) man page.

实际上, -1至-4095表示错误,其他表示成功. glibc的通用syscall(2)包装器使用以下顺序:/jae SYSCALL_ERROR_LABEL,显然是保证对所有Linux系统调用都是面向未来的.有趣的情况包括mmap,其中有效地址可以设置符号位,但必须进行页面对齐getpriority,其中内核ABI将-20..19返回值范围映射到1..40,并由libc对其进行解码. 有关解码系统调用错误返回值的相关答案的详细信息.

Actually, -1 to -4095 means error, anything else means success. glibc's generic syscall(2) wrapper uses this sequence: cmp rax, -4095 / jae SYSCALL_ERROR_LABEL, which is apparently guaranteed to be future-proof for all Linux system calls. Interesting cases include mmap where valid addresses can have the sign bit set, but must be page aligned, and getpriority where the kernel ABI maps the -20..19 return-value range to 1..40, and libc decodes it. More details in a related answer about decoding syscall error return values.

更新,是的,对于-4095 .. -1是运行Linux的所有体系结构上的错误范围,对于所有syscall绝对可以保证.有关更多详细信息,请参见 AOSP非显而易见的syscall()实现. (将来,不同的体系结构可以为MAX_ERRNO使用不同的值,但是可以保证现有拱门(如x86-64)的值与Linux保持内核ABI稳定的不中断用户空间策略的一部分相同. )

Update, yes it's definitely guaranteed for all syscalls that -4095 .. -1 is the range of errors on all architectures Linux runs on. See AOSP non-obvious syscall() implementation for more details. (In the future, a different architecture could use a different value for MAX_ERRNO, but the value for existing arches like x86-64 is guaranteed to stay the same as part of Linux's don't-break-userspace policy of keeping kernel ABIs stable.)

要查找特定平台的常量的实际数值,您需要在#define d位置找到C头文件.有关详细信息,请参见关于这个问题的我的答案.

To find the actual numeric values of constants for a specific platform, you need to find the C header file where they're #defined. See my answer on a question about that for details.

第2节手册页中记录了每个sys调用的返回值的含义,例如 read(2) . (sys_read是原始系统调用,glibc read()函数是非常薄的包装器.)大多数手册页都有完整的返回值部分.例如

The meanings of return values for each sys call are documented in the section 2 man pages, like read(2). (sys_read is the raw system call that the glibc read() function is a very thin wrapper for.) Most man pages have a whole section for the return value. e.g.

返回值

成功后,返回读取的字节数(零表示 文件末尾),文件位置按此数字前移.它 如果此数字小于字节数,则不是错误 要求;例如,这可能是因为较少的字节
目前可以实际使用(也许是因为我们已经接近
文件,或者因为我们正在从管道或终端读取),或者
因为read()被信号中断.另请参阅注释.

On success, the number of bytes read is returned (zero indicates end of file), and the file position is advanced by this number. It is not an error if this number is smaller than the number of bytes requested; this may happen for example because fewer bytes are
actually available right now (maybe because we were close to end-of-
file, or because we are reading from a pipe, or from a terminal), or
because read() was interrupted by a signal. See also NOTES.

发生错误时,返回-1,并正确设置errno.在这个 情况,是否指定文件位置(如果有)
变化.

On error, -1 is returned, and errno is set appropriately. In this case, it is left unspecified whether the file position (if any)
changes.

请注意,最后一段描述了glibc包装器如何解码该值,并设置errno -EAX如果原始系统调用的返回值为负,则errno=EFAULT,如果原始系统调用返回-EFAULT则返回-1.

Note that the last paragraph describes how the glibc wrapper decodes the value and sets errno to -EAX if the raw system call's return value is negative, so errno=EFAULT and return -1 if the raw system call returned -EFAULT.

有一整节列出了允许read()返回的所有可能的错误代码,以及它们对read()的特殊含义. (POSIX规范了大多数这种行为.)

And there's a whole section listing all the possible error codes that read() is allowed to return, and what they mean specifically for read(). (POSIX standardizes most of this behaviour.)

我不确定glibc到底在哪里解码 mmap(2) ,其中返回值不是带符号的类型.它可能使用与通用syscall包装器相同的方法(检查无符号值> -4096UL),但是每个系统调用的特定包装器没有实际在寄存器之间改组arg并调用该函数的开销.

I'm not sure exactly where glibc decodes return values for mmap(2), where the return value is not a signed type. It probably uses the same method as the generic syscall wrapper (checking for unsigned value > -4096UL), but the specific wrappers for each system call don't have the overhead of actually shuffling the args between registers and calling that function.

我没有看到它在glibc源代码树中;大概它埋在宏的某些层下.例如在x86中 -64宏

I'm not seeing it in the glibc source tree; presumably it's buried under some layers of macros. e.g. in the x86-64 macro

这篇关于Assembly中系统调用的返回值是多少?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆