2

我在汇编中返回 errno 时遇到问题。我知道如何找到它,但我无法返回 errno 和返回值。如果我的函数失败,我将返回 errno(由系统调用设置)和 -1。我必须为学校科目做这个。我必须在汇编中创建一个小库,最后一个函数是“写”。我使用调用系统写,但我还必须管理errno。

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

我是正确的还是完全错误的?

我使用了 Assembly Intel x86 并使用 NASM 进行编译。

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

4

2 回答 2

7

errno并不总是全局变量。它只需要是一个左值,并且可能是一个隐藏函数调用的宏。从规范

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

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

你最好有一个调用汇编函数和集合的 C 包装器errno


编辑:由于您不能使用 C 函数(IMO 是没有意义的,因为errno它确实是 C/POSIX 概念),因此您必须自己实现errno收集。找到errnoin的定义errno.h,并实现汇编中的任何内容。例如,我的errno.h定义errno

extern int * __error(void);
#define errno (*__error())

因此,我会调用__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)
        ...

您的系统可能会有不同的errno.

于 2013-03-08T23:08:56.883 回答
1

如果你只是在汇编中编写,你为什么需要errno呢? errno是 C 库函数使用的 C 语言概念,这些函数进行系统调用以将这些系统调用的错误返回传达回 C 代码。如果你真的需要它,最简单的方法是按照 nneonneo 描述并编写一个 C 函数来获取地址errno并从你的汇编代码中调用它。

但是,如果您正在编写汇编代码,则不需要它。系统调用自己在正常返回位置(x86 上的 eax)返回错误代码,并通过一种方式将其与非错误返回区分开来。在 Linux 中,错误总是在 -4095..-1 范围内。该范围内的任何返回值都是错误,超出该范围的任何返回值都是非错误返回。在其他 UNIX 风格(例如 *BSD)中,错误会设置 CARRY 标志。

于 2013-03-08T23:54:31.433 回答