5

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

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

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

4

2 に答える 2

4

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

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

編集: Linux の場合:

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

したがって、アセンブリから、0 や -1 などの不条理な値で呼び出して、現在の値を取得できます。

brk を介して割り当てられたメモリを「解放」できないことに注意してください。C で記述された malloc 関数にリンクしたいだけかもしれません。アセンブリから C 関数を呼び出すことは難しくありません。

于 2012-04-25T19:09:55.330 に答える
0

ソース:

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

アセンブリ出力オプションを使用してコンパイルする

gcc -S -o test.S test.c

次に、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:

それに対するシステムコールはありませんが、それでもコールを行うことができるはずです

于 2012-04-25T19:13:38.803 に答える