errno 并不总是全局变量。它只需要是一个左值,并且可能是一个隐藏函数调用的宏。来自the specification:
未指定 errno 是宏还是用外部链接声明的标识符。
事实上,它通常不是一个全局变量,因为它通常被实现为线程局部的(因此需要一个函数调用来检索一个指向 TLS 块的指针)。
最好有一个调用汇编函数并设置 errno 的 C 包装器。
编辑:由于您不能使用 C 函数(这在 IMO 中毫无意义,因为 errno 是一个 C/POSIX 概念),您将不得不自己实现 errno。在errno.h 中找到errno 的定义,并实现汇编中的任何内容。例如,我的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 实现。