36

I'm looking for some good code examples of dynamic memory allocation using an assembly language under Linux and using system calls, not malloc and friends.

What are some of the simplest but effective ways to do this?

On Intel 386+ computers.

mudgen
  • 7,213
  • 11
  • 46
  • 46
  • http://programmedlessons.org/AssemblyTutorial/Chapter-33/ass33_1.html take a look here it has your question in the header, it looks like it's done like a class. might help. – Justin Gregoire May 06 '10 at 14:56

4 Answers4

17

On Linux mmap2 is a sensible system call to use for this at a low level. It takes 6 arguments, so in IA32 you can call it using:

    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

(See the relevant kernel source for details on the parameter passing)

I built this with NASM and verified it worked using strace, which produced:

mmap2(NULL, 4096, PROT_READ|PROT_WRITE|PROT_EXEC, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xf77ae000
Flexo
  • 87,323
  • 22
  • 191
  • 272
  • Error to be fixed: `(0x02 | 0x20)` is 34, not 22. Also, `PROT_EXEC` is not required to allocate memory. – Hibou57 May 03 '13 at 21:23
  • @Hibou57 Unless I'm missing something `$22` is hex 22 which is correct for `(0x02|0x20)`. It doesn't need exec, but the example code I had been writing needed it so I left it as was. – Flexo May 04 '13 at 08:53
  • Yes, you're right, that's using the NASM syntax (I erroneously red it as a `gas` literal). Note: about the file descriptor being -1, I've checked amd64 (not the same assembly listing, of course) requires 0, and return `-EINVAL` with -1. On i386 both -1 and 0 works, so at least taking i386 and amd64, into account, 0 is more portable than -1, at least since kernel Linux 2.8. – Hibou57 May 09 '13 at 03:40
  • Could you please also give some hints for how to free the space allocated? Thank you. – AuBee Dec 07 '16 at 20:26
  • @AuBee `munmap(void*,size_t)` - basically you only need to set EAX (syscall number - 91 I think), EBX (address) and ECX (length). – Flexo Dec 07 '16 at 20:47
10

brk(2). And take a look at ELF.

Nikolai Fetissov
  • 82,306
  • 11
  • 110
  • 171
4

An alternative to brk() is to use the mmap() system call, with MAP_ANONYMOUS | MAP_PRIVATE.

caf
  • 233,326
  • 40
  • 323
  • 462
3

Use the brk system call to change the end of your data segment.

Take a look here: http://www.linuxjournal.com/article/6390 to understand what you're doing.

WhirlWind
  • 13,974
  • 3
  • 42
  • 42