我有一个问题是在程序集中返回errno。我知道如何找到它,但我不能返回errno和返回值。如果我的函数失败,我将返回errno(通过系统调用设置)和-1。 我必须为学校课程这样做。我必须在汇编中创建一个小库,最后一个函数是“write”。我使用call system write,但我也要管理errno。
如果我没弄错的话,errno是一个全局变量。所以我想在汇编中恢复它,并改变它的价值,但我还没有在我的功能中恢复它......
我是好的还是完全错的?
我使用了Assembly Intel x86,我使用NASM编译。
抱歉语言错误,我不是英语。
答案 0 :(得分:5)
errno
并不总是全局变量。它只需要是左值,并且可以是隐藏函数调用的宏。来自the specification:
未指定errno是宏还是使用外部链接声明的标识符。
实际上,它通常不是一个全局变量,因为它通常被实现为线程本地的(因此需要函数调用来检索指向TLS块的指针)。
最好有一个C包装器调用汇编函数并设置errno
。
errno
坚定地是C / POSIX概念),你必须自己实现errno
收集。在errno
中找到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
的不同实现。
答案 1 :(得分:1)
如果您只是在集会中写作,为什么还需要errno
? errno
是C库函数使用的C语言概念,它使系统调用将错误返回从那些系统调用返回到C代码。如果你确实需要它,最简单的方法就是在nneonneo描述并编写一个C函数时获取errno
的地址并从汇编代码中调用它。
但如果您正在编写纯汇编代码,则不需要它。系统调用本身在正常返回位置(x86上为eax)返回错误代码,并将其与非错误返回区分开来。在Linux中,错误始终在-4095 ..- 1范围内。该范围内的任何返回值都是错误,除此之外的任何内容都是非错误返回。在其他UNIX风格(例如* BSD)中,错误设置了CARRY标志。