Как динамически распределять память с помощью сборок и системных вызовов под Linux

18

Я ищу хорошие примеры кода для распределения динамической памяти с использованием языка ассемблера под Linux и использования системных вызовов, а не malloc и друзей.

Каковы некоторые из простейших, но эффективных способов сделать это?

На компьютерах Intel 386+.

    
задан mudge 06.05.2010 в 16:54
источник
  • programmedlessons.org/AssemblyTutorial/Chapter-33/ass33_1.html посмотрите здесь, у вас есть свой вопрос в заголовке, похоже, что это делается как класс. может помочь. –  Justin Gregoire 06.05.2010 в 16:56

4 ответа

5

brk(2) . Посмотрите ELF .

    
ответ дан Nikolai Fetissov 06.05.2010 в 16:58
  • Что такое «сегмент данных», на который ссылается справочная страница? –  mudge 06.05.2010 в 17:09
  • См. ссылку ELF выше. –  Nikolai Fetissov 06.05.2010 в 17:14
8

В Linux mmap2 - разумный системный вызов для использования на этом уровне на низком уровне. Он принимает 6 аргументов, поэтому в IA32 вы можете вызвать его, используя:

    mov eax, 192    ; mmap2
    xor ebx, ebx    ; addr = NULL
    mov ecx, 4096   ; len = 4096
    mov edx,      ; prot = PROT_READ|PROT_WRITE|PROT_EXEC
    mov esi,     ; flags = MAP_PRIVATE|MAP_ANONYMOUS
    mov edi, -1     ; fd = -1
    xor ebp, ebp    ; offset = 0 (4096*0)
    int          ; make call

(Подробнее см. соответствующий источник ядра ). при прохождении параметра)

Я построил это с помощью NASM и проверил, что он работал с использованием strace , который произвел:

mmap2(NULL, 4096, PROT_READ|PROT_WRITE|PROT_EXEC, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xf77ae000
    
ответ дан Flexo 12.12.2012 в 23:57
  • Ошибка исправления: (0x02 | 0x20) - 34, а не 22. Кроме того, PROT_EXEC не требуется выделять память. –  Hibou57 03.05.2013 в 23:23
  • @ Hibou57 Если я не пропущу что-то, то $ 22 - это hex 22, который корректен для (0x02 | 0x20). Это не нужно exec, но код примера, который я писал, нуждался в этом, поэтому я оставил его как есть. –  Flexo♦ 04.05.2013 в 10:53
  • Да, вы правы, это использует синтаксис NASM (я ошибочно краснул его как газовый литерал). Примечание: о файловом дескрипторе, равном -1, я проверил amd64 (не тот список сборок, конечно), которому требуется 0, и возвратите -EINVAL с -1. На i386 работают как -1, так и 0, поэтому, по крайней мере, принимая во внимание i386 и amd64, 0 более переносимо, чем -1, по крайней мере, с ядра Linux 2.8. –  Hibou57 09.05.2013 в 05:40
  • Не могли бы вы также дать некоторые подсказки о том, как освободить выделенное пространство? Спасибо. –  AuBee 07.12.2016 в 21:26
  • @AuBee munmap (void *, size_t) - в основном вам нужно всего лишь установить EAX (номер самонастройки - 91, я думаю), EBX (адрес) и ECX (длина). –  Flexo♦ 07.12.2016 в 21:47
2

Альтернативой brk() является использование системного вызова mmap() , MAP_ANONYMOUS | MAP_PRIVATE .

    
ответ дан caf 07.05.2010 в 08:10
1

Используйте системный вызов brk для изменения конца сегмента данных.

Посмотрите здесь: Ссылка , чтобы понять, что вы делаете.

    
ответ дан WhirlWind 06.05.2010 в 16:57
  • Спасибо. Я начал читать эту статью. Это потрясающе. –  mudge 06.05.2010 в 17:06