5

因此,作为一项挑战和性能,我正在编写一个简单的汇编服务器。我知道的唯一方法是通过系统调用。(通过int 0x80)显然,我需要比在组装或加载时分配的更多内存,所以我阅读并决定我想使用sbrk(),主要是因为我不理解mmap():p

无论如何,Linux 没有为 sbrk() 提供中断,只有 brk()。

那么...如何找到当前程序中断以使用 brk()?我考虑过使用 getrlimit(),但我不知道如何获取资源(我猜是进程 ID)传递给 getrlimit()。或者我应该找到其他方法来实现 sbrk()?

4

2 回答 2

4

sbrk 函数可以通过获取当前值并手动减去所需数量来实现。一些系统允许您使用 获取当前值brk(0),而其他系统则在一个变量中跟踪它[该变量使用 的地址进行初始化,该地址_end由链接器设置为指向初始中断值]。

这是一个非常特定于平台的东西,所以 YMMV。

编辑:在 Linux 上:

但是,实际的 Linux 系统调用会在成功时返回新的程序中断。失败时,系统调用返回当前中断。glibc 包装函数做了一些工作(即检查新的中断是否小于 addr)以提供上述 0 和 -1 返回值。

因此,从汇编中,您可以使用 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 回答