Assembly 如何在程序集中返回errno?

Assembly 如何在程序集中返回errno?,assembly,x86,errno,Assembly,X86,Errno,我在程序集中返回errno时遇到问题。我知道如何找到它,但我不能返回errno和返回值。如果函数失败,我将返回errno(通过系统调用设置)和-1。 我必须为一门学校科目做这件事。我必须在汇编中创建一个小库,最后一个函数是“write”。我使用呼叫系统编写,但我还必须管理errno 如果我没有弄错的话,errno是一个全局变量。所以我想在汇编中恢复它,并更改它的值,但我还没有成功地在函数中恢复它 我是在好的方面还是完全错了 我使用汇编英特尔x86,并使用NASM编译 抱歉,语言错误,我不是英国人

我在程序集中返回errno时遇到问题。我知道如何找到它,但我不能返回errno和返回值。如果函数失败,我将返回errno(通过系统调用设置)和-1。 我必须为一门学校科目做这件事。我必须在汇编中创建一个小库,最后一个函数是“write”。我使用呼叫系统编写,但我还必须管理errno

如果我没有弄错的话,errno是一个全局变量。所以我想在汇编中恢复它,并更改它的值,但我还没有成功地在函数中恢复它

我是在好的方面还是完全错了

我使用汇编英特尔x86,并使用NASM编译


抱歉,语言错误,我不是英国人。

errno
并不总是一个全局变量。它只需要是左值,也可以是隐藏函数调用的宏。发件人:

未指定errno是宏还是使用外部链接声明的标识符

事实上,它通常不是全局变量,因为它通常被实现为线程本地变量(因此需要函数调用来检索指向TLS块的指针)

最好使用调用汇编函数并设置
errno
的C包装器


编辑:由于您不能使用C函数(在我看来,这是毫无意义的,因为
errno
绝对是C/POSIX概念),因此您必须自己实现
errno
。在
errno.h
中找到
errno
的定义,并实现程序集中的任何内容。例如,my
errno.h
errno
定义为

extern int * __error(void);
#define errno (*__error())
因此,我将调用
\u error
函数(返回
int*
),然后存储到返回的地址。例如,以下是我的系统为设置
errno
而生成的程序集:

$ gcc -xc - -o- -S <<EOF
#include <errno.h>
main() { errno = 3; return 0; }
EOF
    .section    __TEXT,__text,regular,pure_instructions
    .globl  _main
    .align  4, 0x90
_main:
Leh_func_begin1:
    pushq   %rbp
Ltmp0:
    movq    %rsp, %rbp
Ltmp1:
    subq    $16, %rsp
Ltmp2:
    callq   ___error
    movl    $3, (%rax)
        ...

$gcc-xc--o--S如果您只在汇编中编写,为什么需要
errno
errno
是一种C语言概念,由C库函数使用,这些函数进行系统调用,以将这些系统调用返回的错误传递回C代码。如果您真的需要它,最简单的方法就是按照nneonneo的描述编写一个C函数,该函数获取
errno
的地址,并从汇编代码中调用它


但如果您正在编写纯汇编代码,则不需要它。系统在正常返回位置(x86上的eax)调用自身返回错误代码,以将其与非错误返回区分开来。在Linux中,错误总是在-4095..-1范围内。该范围内的任何返回值都是错误,超出该范围的任何值都是非错误返回。在其他UNIX版本(*BSD)中,错误设置进位标志。

谢谢您的回答,我现在更了解errno的工作原理。但我不能在C中使用包装器,因为它是一门学校课程,我只能使用汇编代码。我必须在汇编中执行一些库(~10个函数),最后一个函数需要errno。真的吗?你应该更新你的问题以反映这一点。我会更新答案。我已经更新了我的问题。我试着应用你在明天最后一次编辑中解释的内容。谢谢:)或者,编译获取/设置
errno
的函数并查看它生成的程序集(例如,使用
gcc-S
)。@tc.:是的,这是个好主意。例如,我为我的
errno
添加了程序集。我需要errno,因为这些函数(用纯程序集代码编写是)将由C中的函数调用。大多数情况下,我将在C中使用此库,而不是在程序集代码中使用。