【问题标题】:Linux sbrk() as a syscall in assemblyLinux sbrk() 作为汇编中的系统调用
【发布时间】:2012-05-06 12:21:59
【问题描述】:

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

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

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

【问题讨论】:

  • 欢迎来到 Stack Overflow! “我知道的唯一方法是通过系统调用。”。还有一些库调用,例如sbrk。还是您的意思是“在没有 libc 的汇编中”?
  • 我不确定如何调用库。 (但仍然不知道如何)你认为库调用比系统调用快吗?
  • mmap 很简单。不过,这对于小额分配并不好。

标签: linux assembly system-calls sbrk


【解决方案1】:

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

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

编辑:在 Linux 上:

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

所以从汇编中,你可以用 0 或 -1 之类的荒谬值调用它来获取当前值。

请注意,您不能“释放”通过 brk 分配的内存 - 您可能只想链接用 C 编写的 malloc 函数。从程序集中调用 C 函数并不难。

【讨论】:

  • 或者 OP 可以使用 MAP_ANONYMOUS|MAP_PRIVATE 进行 mmap 系统调用来获取内存,并使用 munmap 来释放它。这比在用户空间中自己管理内存更昂贵,但从汇编中更容易做到......
  • “请注意,您不能“释放”通过 brk 分配的内存”。但是man brk 说“增加程序中断会为进程分配内存;减少中断会释放内存。”那么为什么不能“释放”通过 brk 分配的内存呢?
  • @automaton 这样做是不安全的,因为您在分配内存后调用的其他一些函数可能已经在它“之上”分配了更多内存。你必须编写一个完整的内存管理系统。
【解决方案2】:

来源:

#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:

没有系统调用,但您应该仍然可以进行调用

【讨论】:

  • 我在 fedora16/x86 上链接了二进制静态文件,并且 objdumped。我看到 __sbrk 调用 __brk 调用 brk 系统调用(系统调用 45)
  • 也许吧,但您发布的内容仍然取决于链接的 _sbrk 的外部实现
  • 是的,正如我提到的,sbrk 没有系统调用(至少在我的机器上,我有理由确定它作为系统调用被排除在 Unix 标准之外)所以调用 sbrk 你需要将其链接到 libc 应该已实现。
猜你喜欢
  • 2016-01-16
  • 2015-09-24
  • 2014-05-24
  • 2012-01-20
  • 1970-01-01
  • 2010-12-15
  • 2010-12-18
  • 2020-08-14
  • 2015-05-03
相关资源
最近更新 更多