如何在Linux下使用汇编语言和系统调用动态分配内存

39

我正在寻找一些使用Linux下的汇编语言和系统调用进行动态内存分配的良好代码示例,而不是使用malloc等函数。

有哪些最简单但有效的方法可以做到这一点?

在Intel 386+计算机上。


看一下这里:http://programmedlessons.org/AssemblyTutorial/Chapter-33/ass33_1.html,它在标题中有你的问题,看起来像是用类的方式完成的。可能会有所帮助。 - Justin Gregoire
4个回答

18
在Linux中,mmap2是一个在低级别上使用的明智系统调用。它有6个参数,在IA32中可以使用以下方式调用:
    mov eax, 192    ; mmap2
    xor ebx, ebx    ; addr = NULL
    mov ecx, 4096   ; len = 4096
    mov edx, $7     ; prot = PROT_READ|PROT_WRITE|PROT_EXEC
    mov esi, $22    ; flags = MAP_PRIVATE|MAP_ANONYMOUS
    mov edi, -1     ; fd = -1
    xor ebp, ebp    ; offset = 0 (4096*0)
    int $80         ; make call

详情请参考有关参数传递的内核源代码

我使用了NASM来构建它,并通过strace进行验证,结果如下:

mmap2(NULL, 4096, PROT_READ|PROT_WRITE|PROT_EXEC, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xf77ae000

需要修复的错误:(0x02 | 0x20) 应该是34,而不是22。此外,分配内存时不需要使用 PROT_EXEC - Hibou57
@Hibou57 除非我漏掉了什么,$22 是十六进制的 22,这对于 (0x02|0x20) 是正确的。它不需要使用 exec,但是我之前编写的示例代码需要它,所以我保留了原样。 - Flexo
是的,你说得对,那是使用NASM语法(我错误地将其视为“gas”文字)。注意:关于文件描述符为-1,我已经检查过amd64(当然不是相同的汇编清单)需要0,并返回-EINVAL与-1。在i386上,-1和0都可以工作,因此至少考虑到i386和amd64,0比-1更具可移植性,至少自Linux 2.8内核以来如此。 - Hibou57
请问您能否提供一些如何释放已分配空间的提示?谢谢。 - AuBee
@AuBee munmap(void*,size_t) - 基本上你只需要设置EAX(系统调用号-我想是91),EBX(地址)和ECX(长度)。 - Flexo

11

brk(2)是与内存相关的一个系统调用。同时,你也可以查看ELF


4

使用 MAP_ANONYMOUS | MAP_PRIVATE 调用 mmap() 系统调用是 brk() 的另一种选择。


3

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接