2017-02-02 13 views
0

GDBで、__NR_write操作を呼び出した直後に、__NR_lchownシステムコール番号(16)がraxレジスタに渡されていることに気づきました。私が得たコードは次のとおりです。操作後にsyscall __NR_lchownが登録されるのはなぜですか?

.data 

BemVindo: .ascii "Seja bem vindo!\n" 
Digite: .ascii "Digite alguma coisa\n" 

_start: 

    mov $4, %rax 
    mov $1, %rbx 
    mov $BemVindo, %rcx 
    mov $16, %rdx 
    int $0x80 

    mov $4, %rax # had to add this line because I was assuming that value 4 was still there in the register 
    mov $Digite, %rcx 
    mov $20, %rdx 
    int $0x80 

unistd.hによると:私はLinux上でだので、

#define __NR_write 4 
#define __NR_lchown 16 

だから、私はこのlchownは、コマンドchownコマンドの権利とは何かを持っている必要がありますと仮定しますか?とにかく、問題は、なぜ私は操作を呼び出した直後に値16がロードされているのですか?

答えて

4

Linuxでのシステムコールは、C関数と同様に独自の「呼び出し規約」に従います。コードが使用しているint $0x80システムコールインターフェイスは、32ビットx86システムコール規約に従います。特にこの規約では、システムコールの戻り値がEAXに返されます。 writeシステムコールの戻り値はファイルに書き込まれたバイト数なので、EAXはあなたが書いている文字列の長さに変更されます。私は他のすべてのレジスタが保存されていると信じています。

64ビットコードでは、32ビットコードではなく64ビットx86システムコールインターフェイスを使用する必要があります。 32ビットインタフェースは32ビットレジスタのみを使用するので、表示しようとしている文字列が最初の4GBのメモリにない場合、プログラムは失敗します。 64ビット・インタフェースは、32ビット・インタフェースとは異なるシステム・コール番号を持ち、異なるレジスタを使用して引数を渡し、INTの代わりにSYSCALL命令を使用します。

関連する問題