3

システムコールを実行するプログラムを作成しようとしていfork()ますが、子/親はそれぞれ異なる文字列とexit(0).

問題は -fork()成功しましたが (2 行の出力が表示されるため)、何らかの理由で親プロセスと子プロセスの両方が親文字列を出力することです。

コードは次のとおりです。

BITS 64

section .data
msg1:    db    "Hello from child", 0x0a
len1:    equ   $-msg1
msg2:    db    "Hello from parent", 0x0a
len2:    equ   $-msg2

section .text
global start

start:
        xor rax,rax
        mov rax,0x2000002    ; fork() syscall
        syscall

        test eax,eax
        jne flow_parent

        mov rax, 0x2000004   ; SYS_write
        mov rdi, 1           ; stdout
        mov rsi, msg1
        mov rdx, len1
        syscall

        xor rdi,rdi
        mov rax,0x2000001
        syscall

flow_parent:
        mov rax, 0x2000004   ; SYS_write
        mov rdi, 1           ; stdout
        mov rsi, msg2
        mov rdx, len2
        syscall

        xor rdi,rdi
        mov rax,0x2000001
        syscall

私の出力:

$ nasm -f macho64 code.s -o code.o
$ ld -o code -e start -macosx_version_min 10.7 code.o
$ ./code
Hello from parent
Hello from parent
$

これを修正する方法についてのアイデアはありますか?

4

2 に答える 2

6

まず、Mac OS X で syscall を作成していて、それが Linux カーネルと同じように動作することを前提にしていますが、これは明らかに間違っています (Linux フォーク syscall 規則 != XNU フォーク syscall 規則)。Mac OS X は、ユーザーが libSystem ライブラリを介さずに直接システム コールを行うことをサポートしていません。

それはさておき、実行している XNU カーネルのバージョンはわかりませんが、実際にlibsyscall ライブラリのfork 関数のソース コードを見てみると、edx レジスタが代わりに (orl %edx, %edx) を使用して、プロセスが子であるか親であるかを判断します。

繰り返しますが、これは、Apple が望むように将来インターフェイスを簡単に変更する可能性があるため、これを実装するための信頼できる方法ではありません。

于 2013-11-14T18:04:32.283 に答える