2

アセンブリで errno を返すのに問題があります。見つけ方はわかっているのですが、errno と戻り値を返すことができません。関数が失敗した場合は、errno (システム コールによって設定) と -1 を返します。私は学校の科目のためにこれをしなければなりません。アセンブリで小さなライブラリを作成する必要があり、最後の機能は「書き込み」です。私は call システム write を使用していますが、errno も管理する必要があります。

私が間違っていなければ、errno はグローバル変数です。だから私はアセンブリでそれを回復し、その値を変更することを考えていますが、私はまだ自分の機能でそれを回復することに成功していません...

私は良い方向に進んでいますか、それとも完全に間違っていますか?

Assembly Intel x86 を使用し、NASM でコンパイルしました。

言語の間違いで申し訳ありません。私は英語ではありません。

4

2 に答える 2

7

errno常にグローバル変数であるとは限りません。左辺値であることが必要なだけで、関数呼び出しを隠すマクロの場合もあります。仕様から:

errno がマクロであるか、外部リンケージで宣言された識別子であるかは指定されていません。

実際、通常はグローバル変数ではありません。これは通常、スレッド ローカルに実装されるためです (そのため、TLS ブロックへのポインターを取得するには関数呼び出しが必要です)。

アセンブリ関数を呼び出して を設定する C ラッパーを使用することをお勧めしますerrno


errno編集:C関数(IMOは、しっかりと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 に答える