如何在Assembly中返回errno?

时间:2013-03-08 23:04:44

标签: assembly x86 errno

我有一个问题是在程序集中返回errno。我知道如何找到它,但我不能返回errno和返回值。如果我的函数失败,我将返回errno(通过系统调用设置)和-1。 我必须为学校课程这样做。我必须在汇编中创建一个小库,最后一个函数是“write”。我使用call system write,但我也要管理errno。

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

我是好的还是完全错的?

我使用了Assembly Intel x86,我使用NASM编译。

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

2 个答案:

答案 0 :(得分:5)

errno并不总是全局变量。它只需要是左值,并且可以是隐藏函数调用的宏。来自the specification

  

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

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

最好有一个C包装器调用汇编函数并设置errno


编辑:由于你不能使用C函数(IMO,这是无意义的,因为errno坚定地是C / POSIX概念),你必须自己实现errno收集。在errno中找到errno.h的定义,并实现汇编中的任何内容。例如,我的errno.herrno定义为

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的不同实现。

答案 1 :(得分:1)

如果您只是在集会中写作,为什么还需要errnoerrno是C库函数使用的C语言概念,它使系统调用将错误返回从那些系统调用返回到C代码。如果你确实需要它,最简单的方法就是在nneonneo描述并编写一个C函数时获取errno的地址并从汇编代码中调用它。

但如果您正在编写汇编代码,则不需要它。系统调用本身在正常返回位置(x86上为eax)返回错误代码,并将其与非错误返回区分开来。在Linux中,错误始终在-4095 ..- 1范围内。该范围内的任何返回值都是错误,除此之外的任何内容都是非错误返回。在其他UNIX风格(例如* BSD)中,错误设置了CARRY标志。