Грамотное выделение памяти на FASM

Тема в разделе "WASM.BEGINNERS", создана пользователем rococo795, 2 дек 2016.

  1. rococo795

    rococo795 Active Member

    Публикаций:
    0
    Регистрация:
    1 дек 2016
    Сообщения:
    236
    invoke GetProcessHeap
    mov [GetProcessHeapMem],eax
    invoke HeapAlloc,[GetProcessHeapMem],0,$1aeaa0
    cmp eax,0
    je .errHeapAlloc
    mov [HeapAllocMem],eax

    invoke HeapFree,[GetProcessHeapMem],0,[HeapAllocMem]

    1. Как более грамотно выделить память
    2. Как грамотно завершить процессы с ней
    3. Пусть мне нужно 1000 байт памяти... Как лучше поступать - выделять именно 1000 байт.... или прибавить один... или прибавить больше?? Как будет надёжнее???

    Заранее благодарен за ответы...
     
  2. RET

    RET Well-Known Member

    Публикаций:
    17
    Регистрация:
    5 янв 2008
    Сообщения:
    789
    Адрес:
    Jabber: darksys@sj.ms
    Во первых - наконец то привет Васму ;)
    По теме: если вам надо так мало памяти - то проще и достаточно взять из стэка.
     
  3. rococo795

    rococo795 Active Member

    Публикаций:
    0
    Регистрация:
    1 дек 2016
    Сообщения:
    236
    Привет..
    1. Я про смысл - есть ли какой то смысл в том, чтобы выделять память с запасом, или это ни к чему.
    2. А с каких величин стоит переходить от стека к выделению функцией?
     
  4. _edge

    _edge Well-Known Member

    Публикаций:
    1
    Регистрация:
    29 окт 2004
    Сообщения:
    631
    Адрес:
    Russia
    Внесу свои 5 копеек

    Что оптимальнее из разных варантов (скорость), обсуждалось:

    http://web.archive.org/web/20020314161942/http://mastest.chat.ru/
    http://www.gamedev.ru/code/forum/?id=42061
    https://habrahabr.ru/post/158347/
    http://f0dder.reteam.org/memalloc.htm

    Еще, GetProcessHeap можно реализовать руками, просто вставив код самого GetProcessHeap (на других виндах, по идее, тоже должно работать)

    MOV EAX,FS:[18h]
    MOV EAX,[EAX+30h]
    MOV EAX,[EAX+18h]

    Есть вопросы по heap'у. В интернетах говорится, что по умолчанию он имеет размер 1 мб для процесса, но карта памяти Олли показывает каждый раз разные небольшого размера куски.
     
  5. rococo795

    rococo795 Active Member

    Публикаций:
    0
    Регистрация:
    1 дек 2016
    Сообщения:
    236
    Поучительно... Спасибо...
     
  6. Mikl___

    Mikl___ Супермодератор Команда форума

    Публикаций:
    14
    Регистрация:
    25 июн 2008
    Сообщения:
    3.797
    rococo795,

    Выделение памяти напрямую через системные функции ― не самая удачная идея. Поэтому обычно в программе для управления памятью используют другой механизм: «кучу» (heap).
    Иногда термин «куча» употребляют как синоним термина «динамическая память». Куча (по определению) ― это название структуры данных, с помощью которой реализована динамически распределяемая память приложения.
    Так же термин «куча» употребляется когда ссылаются на вполне конкретный механизм (например: системную кучу процесса или любой другой менеджер памяти).
    Далее под кучей понимается динамическая память. Но не любая динамическая память ― куча. Память, выделяемую через VirtualAlloc(Ex), будем называть «динамической памятью», но не «кучей». А под «кучей» будем понимать дополнительный код по управлению памятью, реализованный «поверх» динамической памяти: так называемый «менеджер памяти» или «диспетчер кучи».
    Смысл кучи сводится к обработке множества запросов на создание/разрушение множества мелких объектов (блоков памяти). «Голая» динамическая память (черезVirtualAlloc(Ex)) крайне плохо приспособлена к этой задаче (из-за ограничений на кратность выделения и размера). Различные менеджеры памяти созданы для решения этой задачи.
    Менеджер памяти представлен функциями GetMem, FreeMem и ReallocMem. Использование GetMem и FreeMem похоже на использование VirtualAlloc и VirtualFree ― разница в меньшем объёме функций (память всегда выделяется только на чтение/запись) и в том, что память берётся не напрямую из системы, а из предварительно выделенной памяти.
    Также «кучей» называют не только сам механизм управления памятью, но и регион адресного пространства, выделенный для нужд кучи. Первоначально этот регион мал или вовсе отсутствует. По мере работы программы (и выделения в ней памяти) специальный диспетчер, управляющий кучами (менеджер памяти), будет расширять этот регион по мере необходимости или создавать новые регионы. А при освобождении блоков памяти в куче менеджер памяти будет возвращает системе соответствующие страницы физической памяти (по мере возможности).
    Куча весьма удобна при создании множества мелких блоков данных. Например, связанными списками и деревьями проще манипулировать, используя именно кучу, а не динамическую память. Преимущество кучи в том, что она позволяет вам игнорировать гранулярность выделения памяти и размер страниц и сосредоточиться непосредственно на своей задаче ― абстрагироваться от особенностей аппаратной части. А недостаток является прямым следствием преимущества: вы теряете прямой контроль над передачей физической памяти и её возвратом системе. Что касается скорости работы, то она сильно зависит от специфики данных. Как правило, менеджер памяти оптимизируется под типичные операции в программе и работа с ним наиболее оптимальна в большинстве случаев. С другой стороны, могут быть вырожденные случаи, когда накладные расходы на управление памяти в куче перевешивают выигрыш от экономии на вызовах ядра (вызов VirtualAlloc(Ex) означает обращение к режиму ядра, а переключение контекстов (пользовательский режим → режим ядра и обратно) ― не самая быстрая операция).
    Стандартный менеджер памяти ― это не единственный диспетчер кучи в вашей программе. Вам также доступны:
    • HeapAlloc/HeapFree
    • LocalAlloc/LocalFree
    • GlobalAlloc/GlobalFree
    • IMalloc.Alloc/IMalloc.Free
    • CoTaskMemAlloc/CoTaskMemFree
    • SHAlloc/SHFree
    Чем они отличаются? Это разные реализации одной идеи. В системе есть несколько менеджеров памяти, которые имеют разные цели и используются в разных случаях. Вышеуказанные функции ― это точки доступа к различным менеджерам памяти. Когда их надо использовать? Когда вам нужно «поговорить» с кодом, который понимает только их. К примеру, буфер обмена Windows работает с GlobalAlloc/GlobalFree.
    Самое главное, нужно помнить правило: «кто девушку ужинает ― тот ее и танцует». Иными словами, если память выделили через GetMem ― то освобождать ее должны через FreeMem, выделили через VirtualAlloc ― освобождать нужно через VirtualFree, через LocalAlloc ― тогда LocalFree...
    взято из Адресное пространство под микроскопом
     
    Последнее редактирование: 2 дек 2016
    6a6kin и _edge нравится это.
  7. rococo795

    rococo795 Active Member

    Публикаций:
    0
    Регистрация:
    1 дек 2016
    Сообщения:
    236
    Спасибо....
     
  8. rmn

    rmn Well-Known Member

    Публикаций:
    0
    Регистрация:
    23 ноя 2004
    Сообщения:
    2.348
    Во-первых, виртуальная, а не динамическая же, ну. Во-вторых, она вообще никак не приспособлена для этой задачи. Virtual-функции - это низкоуровневый способ управления памятью, используемый самой системой и он оперирует целыми страницами памяти. Использовать их в высокоуровневых приложениях, это как читать файлы через порты ввода/вывода, вместо использования CreateFile()/ReadFile().
     
  9. rococo795

    rococo795 Active Member

    Публикаций:
    0
    Регистрация:
    1 дек 2016
    Сообщения:
    236
    Я всё читаю... Спасибо за уточнения...
     
  10. Indy_

    Indy_ Well-Known Member

    Публикаций:
    4
    Регистрация:
    29 апр 2011
    Сообщения:
    4.775
    Система не поддерживает расширение буфера, только в частном случае - стека и вниз. Поэтому часто приходится выделять больший размер буфера , с запасом и затем освобождать не используемую его часть. Это позволяет сделать аллокатор хипа. Кернел аллокатор работает со страничной гранулярностью, поэтому нельзя освободить не используемую часть страничного буфера - при большом числе буферов память будет не эффективно использоваться. Такой аллокатор юзается для спец целей, когда обычный не может быть использован, например при низкоуровневой работе(возможны деадлоки из за рекурсивных вызовов аллокатора реализованного в юм) или манипуляция доступом к памяти.
     
    Mikl___ нравится это.
  11. rococo795

    rococo795 Active Member

    Публикаций:
    0
    Регистрация:
    1 дек 2016
    Сообщения:
    236
    Indy_

    Спасибо.... Не буду умничать... Не всё понятно пока что... Но спасибо!!! А вдруг пригодиться через месяц другой...
     
  12. rmn

    rmn Well-Known Member

    Публикаций:
    0
    Регистрация:
    23 ноя 2004
    Сообщения:
    2.348
    Чем ты тут занимаешься вообще? На старом васме одной из последних тем было про виртуальную память и отличие Virtual* функций от Heap*. Страниц на 10 там разжевали все :)
     
  13. rococo795

    rococo795 Active Member

    Публикаций:
    0
    Регистрация:
    1 дек 2016
    Сообщения:
    236
    Да хорош шутить..... Всё... ! Да занимаюсь всякой уйней... и редко... Эт я активность изображаю, чтоб форум чуть подоживить.... Но чё то не особо оное идёт... И главное никто не обращается с реальными вопросами-проблемами, которые сиюминутно появляются в работе.. Либо все очень умные стали - либо не знаю.... (Не думаю что все стали умны и стали грамотно писАть.... почти везде небось найдётся что умного подсказать... не нет! всё у всех нормуль.... только чем дальше - тем глючных прог всё больше и больше..... )
    Сидю... На медленно падающий снег в свете фонарей смотрю.... Таинство мироздания....
     
  14. nds

    nds Member

    Публикаций:
    0
    Регистрация:
    16 июл 2007
    Сообщения:
    157
    все освоили гугл))
    впрочем непонимающим и он не помогает
    вот поднимется новый адрес форума в поиске и понабегут студенты в тему для начинающих