2012-04-25 5 views
2

私は難題として、そしてパフォーマンスのために、アセンブリで単純なサーバーを作成しています。私が知っている唯一の方法は、システムコール経由です。 (int 0x80を使って)明らかに、アセンブル時やロード時に割り当てられるよりも多くのメモリが必要になるので、読んで、主にmmap()を理解していないためにsbrk()アセンブリ内のsyscallとしてのLinux sbrk()

いずれにしても、Linuxはsbrk()に対して割り込みを提供せず、brk()のみ割り込みを提供します。

だから... brk()を使用するために現在のプログラムブレークを見つけるにはどうすればよいですか?私はgetrlimit()を使うことを考えましたが、getrlimit()に渡すリソース(私が推測するプロセスID)を取得する方法はわかりません。または、sbrk()を実装するための他の方法があるはずですか?

+1

ようこそスタックオーバーフロー! "私が知っている唯一の方法は、システムコール経由です。" 'sbrk'のようなライブラリ呼び出しもあります。あるいは、「libcなしのアセンブリで」という意味ですか? –

+1

ライブラリーコールの作成方法がわかりませんでした。 (やはり実際には分かりません)ライブラリ呼び出しはシステム呼び出しより速いと思いますか? –

+0

'mmap'は単純です。しかし、小さな割り当てにはうまくいかない。 – doug65536

答えて

1

sbrk関数は、現在の値を取得し、必要な量を手動で減算することで実装できます。システムによっては、brk(0)で現在の値を取得できるシステムもあれば、変数[最初のブレーク値を指すようにリンカによって設定された_endのアドレスで初期化された変数]で現在の値を取得するシステムもあります。

これは非常にプラットフォーム固有のものなので、YMMVです。

EDIT:Linux上:

しかし、実際のLinuxシステムコールは、成功した新しいプログラムブレークを返します。失敗すると、システムコールは現在のブレークを返します。 glibcラッパー関数は、上記の0と-1の戻り値を提供するためにいくつかの作業を行います(つまり、新しいブレークがaddrより小さいかどうかをチェックします)。

アセンブリから、0または-1のような不合理な値で呼び出すと、現在の値を取得できます。

brkによって割り当てられたメモリを "解放"できないことに注意してください.Cで書かれたmalloc関数をリンクするだけでよいでしょう。アセンブリからC関数を呼び出すのは難しくありません。

+0

OPは、 'MAP_ANONYMOUS | MAP_PRIVATE'で' mmap'システムコールをメモリに、 'munmap'で解放することができます。これはユーザ空間であなた自身のメモリを管理するよりも高価ですが、アセンブリから行う方がはるかに簡単です... –

+2

"brkで割り当てられたメモリを"解放 "できないことに注意してください。しかし、 'man brk'は、"プログラムブレークを増やすと、プロセスにメモリを割り当てる効果があり、ブレークを減らすとメモリが解放されます。 "だから、どのようにあなたはbrk経由で割り当てられたメモリを "解放"できないのですか? – automaton

+0

@automatonメモリを割り当てた後に呼び出された他の関数が、そのメモリの "上に"より多くのメモリを割り当てている可能性があるので、そうするのは安全ではありません。メモリ管理システム全体を書く必要があります。 – Random832

0

出典:

#include <unistd.h> 
#define SOME_NUMBER 8 
int main() { 
    void *ptr = sbrk(8); 
    return 0; 
} 

コンパイルはそれのためのシステムコールはありませんASMコード

_main: 
Leh_func_begin1: 
    pushq %rbp 
Ltmp0: 
    movq %rsp, %rbp 
Ltmp1: 
    subq $16, %rsp 
Ltmp2: 
    movl $8, %eax 
    movl %eax, %edi 
    callq _sbrk 
    movq %rax, -16(%rbp) 
    movl $0, -8(%rbp) 
    movl -8(%rbp), %eax 
    movl %eax, -4(%rbp) 
    movl -4(%rbp), %eax 
    addq $16, %rsp 
    popq %rbp 
    ret 
Leh_func_end1: 

を見ていますが、べき

gcc -S -o test.S test.c 

次にアセンブリ出力オプションを指定して使用してまだ電話をかけることができます

+0

私はfedora16/x86上のバイナリスタティックとobjdumpedをリンクしました。私は、__sbrkが__brkを呼び出してbrkのシステムコール(システム45)を呼び出すのを見ました。 –

+0

おそらく、投稿した内容はまだ_sbrkの外部実装に依存しています –

+0

はい、sbrkのシステムコールはありません私のマシン上では、システムコールとしてUnix標準から除外されていることが合理的です)、sbrkを呼び出すには 'libc'でリンクされている必要があります。 – lukecampbell

関連する問題