Форум программистов, компьютерный форум, киберфорум
Assembler: Windows/protected mode
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
171 / 5 / 2
Регистрация: 27.11.2024
Сообщений: 45
MASM32

Неправильно считываются символы из буфера с помощью ReadConsoleInput

03.05.2025, 16:30. Показов 1491. Ответов 3

Студворк — интернет-сервис помощи студентам
Assembler
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
.data
    inputRecord     INPUT_RECORD <>
 .data?
    numEventsRead   dd ?
 
INPUT_RECORD struct
    EventType       dw ?
    Event           KEY_EVENT_RECORD <>
INPUT_RECORD ends
 
.code
KeyEvent proc uses ebx esi edi
    
    invoke KeyboardCheck
    ;-----------------------
    .if bKey == 27
        mov fGameOver,0
        mov fCloseConsole,1
    .endif
    ;-----------------------
    ret
KeyEvent endp
 
KeyboardCheck proc uses ebx esi edi
    mov bKey,30h
        ;-----------------------
    invoke PeekConsoleInput,hStdIn,addr inputRecord,1,addr numEventsRead
    ;-----------------------
    .if numEventsRead > 0
        invoke ReadConsoleInput,hStdIn,addr inputRecord,1,addr numEventsRead
        ;-------------------------
        .if inputRecord.EventType == KEY_EVENT
            lea esi,inputRecord
            lea esi,dword ptr[esi+2]
            assume esi:ptr KEY_EVENT_RECORD
            .if [esi].bKeyDown != 0
                movzx eax, [esi].wVirtualKeyCode
                ;-----------------------
                mov bKey,al
            .endif
            assume esi:nothing
        .endif
    .endif
    ;-----------------------
    ret
KeyboardCheck endp
при нажатии на escape условие .if bKey == 27 не соблюдается, хотя по идее должно. подскажите, пожалуйста, что в таком случае можно предпринять?

да, есть функции _khbit и _getch или GetAsyncKeyState, но хочется понять, почему представленный способ не работает
0
Лучшие ответы (1)
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
03.05.2025, 16:30
Ответы с готовыми решениями:

Считывание клавиш (L/R-Alt, L/R-Control, Shift, CapsLock, NumLock, ScrollLock) функцией ReadConsoleInput
Как считать клавиши (L/R-Alt, L/R-Control, Shift, CapsLock, NumLock, ScrollLock) используя функция...

Неправильно считываются большие числа
К примеру следующие команды дают такой вот результат (Nasm): mov dword , 4294967296 ; тут он...

Записать символ в буфер клавиатуры, проверить буфер на наличие в нём символов, и вывести данный символ
Доброго дня всем. Прошу помочь немного с несложной задачей, на использование прерывания INT 16h....

3
Asm/C++/Delphi/Py/PHP/VBA
 Аватар для Jin X
6812 / 2052 / 238
Регистрация: 14.12.2014
Сообщений: 4,305
Записей в блоге: 12
03.05.2025, 17:04
Лучший ответ Сообщение было отмечено Makiavelly Uber как решение

Решение

Структура KEY_EVENT_RECORD не выровнена. У неё 4-байтовое выравнивание.
Т.о. после EventType dw ? должно быть AlignmentPadding dw ?. Ну и в коде [esi+4].

Добавлено через 2 минуты
Зачем вообще так всё усложнять?
Можно же написать проще:
Assembler
1
2
3
4
5
6
7
        .if inputRecord.EventType == KEY_EVENT
            .if inputRecord.KeyEvent.bKeyDown != 0
                mov al, byte ptr inputRecord.KeyEvent.wVirtualKeyCode
                ;-----------------------
                mov bKey,al
            .endif
        .endif
И странно, что у вас нет структуры INPUT_RECORD в windows.h:
Assembler
1
2
3
4
5
6
7
8
9
10
11
INPUT_RECORD STRUCT 
  EventType             WORD ?
  two_byte_alignment    WORD ?
  UNION
    KeyEvent                KEY_EVENT_RECORD            <>
    MouseEvent              MOUSE_EVENT_RECORD          <>
    WindowBufferSizeEvent   WINDOW_BUFFER_SIZE_RECORD   <>
    MenuEvent               MENU_EVENT_RECORD           <>
    FocusEvent              FOCUS_EVENT_RECORD          <>
  ENDS 
INPUT_RECORD ENDS
3
171 / 5 / 2
Регистрация: 27.11.2024
Сообщений: 45
03.05.2025, 17:47  [ТС]
Цитата Сообщение от Jin X Посмотреть сообщение
И странно, что у вас нет структуры INPUT_RECORD в windows.h
да, я вот тоже не понимаю, почему этой структуры нет. зашёл в файл windows.inc, поискал -- нет

Добавлено через 1 минуту
Цитата Сообщение от Jin X Посмотреть сообщение
Зачем вообще так всё усложнять?
первоначально было так, как сделал Вы, но в последствии из-за того, что не получалось реализовать, я решил вручную брать адрес до структуры KEY_EVENT_RECORD

Добавлено через 38 секунд
Цитата Сообщение от Jin X Посмотреть сообщение
Структура KEY_EVENT_RECORD не выровнена. У неё 4-байтовое выравнивание.
сейчас попробую; надеюсь, получится. спасибо за ответ!

Добавлено через 25 минут
Цитата Сообщение от Jin X Посмотреть сообщение
Структура KEY_EVENT_RECORD не выровнена
УРАААААААААААААА СПАСИБО! ПОМОГЛО!
только я не понял. как выравнивание повлияло. мне известно, что от этого зависит обращение процессора к памяти в выравненном состоянии вместо двух раз процессор сможет обратиться только один раз, но как это влияет на валидность операций я не понял. буду думать и искать информацию. если не сложно, то пожалуйста объясните, почему так происходит.
спасибо за решение! долго мучался, не мог понять, в чём проблема
0
Asm/C++/Delphi/Py/PHP/VBA
 Аватар для Jin X
6812 / 2052 / 238
Регистрация: 14.12.2014
Сообщений: 4,305
Записей в блоге: 12
04.05.2025, 21:09
На валидность операций это влияет так, что у вас KeyEvent начинается со смещения 4, а не со смещения 2.
Структуры WinAPI выравниваются по правилам Си.
Каждый элемент выравнивается по адресу, кратному его размеру. Если элемент — тоже структура, то выравнивание всей структуры идёт по наибольшему размеру элемента (читаем здесь).

Т.е. INPUT_RECORD содержит 2 элемента: EventType и Event.
EventType имеет размер WORD, а Event — это union, который содержит в том числе и структуру KEY_EVENT_RECORD. Соответственно, Event будет выравнен по адресу, кратному максимальному выравниванию всех структур (KEY_EVENT_RECORD, MOUSE_EVENT_RECORD и пр). Выравнивание этих структур зависит от максимального размера элементов внутри них. Везде максимальный — это либо BOOL (4 байта, не 1, т.к. это фактически int), либо DWORD (тоже 4 байта). Соответственно, Event выравнивается тоже по 4 байтам.

Итак, предположим, что inputRecord имеет адрес 402000, как и EventType внутри него.
Далее идёт адрес адрес 402002, но Event (KeyEvent) должен быть выравнен по 4 байтам, соответственно, он начнётся с адреса 402004, а 2 байта — просто padding. В Си этот padding создастся автоматически, а в ассемблере его нужно делать ручную.

Добавлено через 3 минуты
В качестве примера:
C++
1
2
3
4
5
6
7
8
struct X {
  DWORD a; // адрес 0, размер 4, паддинг перед элементом a = 0
  BYTE b;  // адрес 4, размер 1, паддинг перед элементом b = 0
  WORD c;  // адрес 6, размер 2, паддинг перед элементом c = 1
  BYTE d;  // адрес 8, размер 1, паддинг перед элементом d = 0
  BYTE e;  // адрес 9, размер 1, паддинг перед элементом e = 0
  DWORD f; // адрес 12, размер 4, паддинг перед элементом f = 2
};
2
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
04.05.2025, 21:09
Помогаю со студенческими работами здесь

Резервировать буфер и занести в этот буфер числа
Составить ASM-модуль, который бы резервировал буфер для размещения данных и заносил в этот буфер...

Как достать из буфера клавиатуры последние 20 символов?
ЗАДАНИЕ: Создать текстовый файл; напечатать в нем текст; по сочетанию клавиш(например Ctrl+P)...

Поместить символ в буфер клавиатуры
Доброго времени суток всем! Взываю кого нибудь о помощи!!!Пишу сервер\клиент на Делфях и мне...

BIOS int 16h: записать символ в буфер клавиатуры, проверить его наличие в буфере, вывести его
Огромная просьба ко всем форумчанам подсказать дилетанту почему код не выполняется так как должен...

Составить программу для ввода строки символов с клавиатуры в буфер и вывод этой строки на экран
Составить программу для ввода строки символов с клавиатуры в буфер и вывод этой строки на экран ...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
4
Ответ Создать тему
Новые блоги и статьи
Символьное дифференцирование
igorrr37 13.02.2026
/ * Программа принимает математическое выражение в виде строки и выдаёт его производную в виде строки и вычисляет значение производной при заданном х Логарифм записывается как: (x-2)log(x^2+2) -. . .
Камера Toupcam IUA500KMA
Eddy_Em 12.02.2026
Т. к. у всяких "хикроботов" слишком уж мелкий пиксель, для подсмотра в ESPriF они вообще плохо годятся: уже 14 величину можно рассмотреть еле-еле лишь на экспозициях под 3 секунды (а то и больше),. . .
И ясному Солнцу
zbw 12.02.2026
И ясному Солнцу, и светлой Луне. В мире покоя нет и люди не могут жить в тишине. А жить им немного лет.
«Знание-Сила»
zbw 12.02.2026
«Знание-Сила» «Время-Деньги» «Деньги -Пуля»
SDL3 для Web (WebAssembly): Подключение Box2D v3, физика и отрисовка коллайдеров
8Observer8 12.02.2026
Содержание блога Box2D - это библиотека для 2D физики для анимаций и игр. С её помощью можно определять были ли коллизии между конкретными объектами и вызывать обработчики событий столкновения. . . .
SDL3 для Web (WebAssembly): Загрузка PNG с прозрачным фоном с помощью SDL_LoadPNG (без SDL3_image)
8Observer8 11.02.2026
Содержание блога Библиотека SDL3 содержит встроенные инструменты для базовой работы с изображениями - без использования библиотеки SDL3_image. Пошагово создадим проект для загрузки изображения. . .
SDL3 для Web (WebAssembly): Загрузка PNG с прозрачным фоном с помощью SDL3_image
8Observer8 10.02.2026
Содержание блога Библиотека SDL3_image содержит инструменты для расширенной работы с изображениями. Пошагово создадим проект для загрузки изображения формата PNG с альфа-каналом (с прозрачным. . .
Установка Qt-версии Lazarus IDE в Debian Trixie Xfce
volvo 10.02.2026
В общем, достали меня глюки IDE Лазаруса, собранной с использованием набора виджетов Gtk2 (конкретно: если набирать текст в редакторе и вызвать подсказку через Ctrl+Space, то после закрытия окошка. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru