Форум программистов, компьютерный форум, киберфорум
Assembler: DOS/Real Mode/16-bits
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.72/18: Рейтинг темы: голосов - 18, средняя оценка - 4.72
0 / 0 / 0
Регистрация: 11.10.2014
Сообщений: 12

Прерывание от клавиатуры с заменой клавиш

11.10.2014, 16:26. Показов 3728. Ответов 3
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Есть задание: необходимо заменить линейку клавиш asd... на символ "стрелка вправо", линейку клавиш zxc... на символ "стрелка вверх", ввод заменённых клавиш реализовать через shift для asd... и ctrl для zxc...
Есть код, писал сам, но почему он так работает в некоторых местах мне не понятно....
Вообщем, принцип таков:
1) Считываем из порта 60h код клавиши
2)Проверяем нажаты ли шифты или контролы, в зависимости от этого идём проверять к какой линейке относится клавиша, потом либо засылаем в буфер клавиатуры код стрелки, либо печатаем символ(через стандартный обработчик)
Вот код:
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
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
JUMPS
segm segment para public 'code'
assume cs:segm, ds:segm
org 100h
start: jmp main
oldint dd ?
mass_asd db 1eh, 1fh, 20h, 21h, 22h, 23h, 24h, 25h, 26h ;
mass_zxc db 2ch, 2dh, 2eh, 2fh, 30h, 31h, 32h ;
strr db 'abcd$'
;для сравнения считанного скан кода клавиатуры
;ищет совпадение с одним из символов массивов, bx - адрес начала, 
;si - кол-во элементов с отсчётом от нуля(сравнивает с последнего)
find_symbol proc far 
cycle:mov dl, [bx][si];загрузка символа для сравнения
    cmp al, dl
    jz cmp_find;
    dec si
    cmp si, 0
    jge cycle;
    mov bl, 0
    jmp ou;
cmp_find: 
    mov bl, 1;
 ou:ret
find_symbol endp
 
;возвращают результат через bl, 1 - нажата, 0 - наоборот
;проверка нажатия одной из клавиш линейки asd
test_asd proc far
    lea bx, mass_asd
    mov si, 8;будем считать до -1 
    call find_symbol
    ret
test_asd endp
 
;проверка нажатия одной из клавиш линейки zxc
test_zxc proc far
    lea bx, mass_zxc
    mov si, 6
    call find_symbol
    ret
test_zxc endp
 
newint09 proc far
    ;необходимо проверить слово флагов клавиатуры на нажатие shift, ctrl
    ;если нажат shift, то необходимо опять сравнить скан код с линейкой asd, если попал, то вывести букву, если нет, от вызывать обработчик клавиатуры
    ;нужно получить слово флагов клавиатуры
    sti
    push ax
    push bx
    push dx
    push di
    push es
    in al, 60h
    mov cl, al
    push ds
    mov ax, 0040h
    mov ds, ax
    mov bx, 0017h
    mov ax, word ptr [ds:bx]
    pop bx
    mov ds, bx;восстановим адрес сегмента данных
    ;сначала Lshift, Rshift
    test ax, 0300h; 0000 0010 0000 0000b
    jnz cmp_asd
    ;теперь Ctrl'ы
    test ax, 0005h; 0000 0100 0000 0000b
    jnz cmp_zxc
    jmp replacement;проверка на нажатие клавиш одной из линеек и если нужно - подмена на стрелки
    
cmp_asd:;при нажатом шифте
    mov al, cl
    call test_asd
    cmp bl, 1
    jz print_asd;можно печатать
    mov al,cl
    call test_zxc
    cmp bl, 1
    jz line_zxc;нажата линейка zxc, заменяем клавишу
    jmp ext;
print_asd:;отжать шифт, вызвать стандартный обработчик для печати буквы
    push ds
    mov ax, 0040h
    mov ds, ax
    mov bx, 0017h
    mov ax, word ptr [ds:bx];вроде как получил...
    and ax, 1111110011111111b;0xf8ff
    mov word ptr[ds:bx], ax;
    pop bx
    mov ds, bx;
    jmp ext
cmp_zxc:
    mov al, cl
    call test_zxc
    cmp bl, 1
    jz print_zxc;можно печатать
    mov al, cl
    call test_asd
    cmp bl, 1
    jz line_asd;подмена клавиши
    jmp ext;
print_zxc:
    push ds
    mov ax, 0040h
    mov ds, ax
    mov bx, 0017h
    mov ax, word ptr [ds:bx];вроде как получил...
    and ax, 1111111111111010b; 
    mov word ptr[ds:bx], ax;
    pop bx
    mov ds, bx;
    jmp ext;
    ;;;;;;;;;;;;;;
    ;если не проработал ни один из вариантов
    ;;;;;;;;;;;;;;
replacement:
    mov al, cl
    call test_asd
    cmp bl, 1
    jz line_asd
    mov al, cl
    call test_zxc
    cmp bl, 1
    jz line_zxc
    jmp ext;
line_zxc:
    mov ax, 0040h
    mov es, ax
    mov di, es:[01ch]
    mov ax, 0050h
    mov es:[di], ax
    cmp di, 03ch
    je beg3
    inc di
    inc di
    jmp save4 
    beg3: mov di, 01eh
    save4: mov es:[01ch], di
    jmp end_ret;
line_asd:
    mov ax, 0040h
    mov es, ax
    mov di, es:[01ch]
    mov ax, 4d00h
    mov es:[di], ax
    cmp di, 03ch
    je beg2
    inc di
    inc di
    jmp save2 
    beg2: mov di, 01eh
    save2: mov es:[01ch], di
    jmp end_ret;
end_ret:
    in al, 61h
    mov ah, al
    or al, 80h
    out 61h, al
    mov al, ah
    out 61h, al
    cli
    mov al, 20h
    out 20h, al
    pop es
    pop di
    pop dx
    pop bx
    pop ax
    iret
ext:
    pop es
    pop di
    pop dx
    pop bx
    pop ax
    jmp cs:[oldint]
 
newint09 endp
;///////////////////////////////////////////////////////
main:
    mov ax, 3509h
    int 21h
    mov word ptr oldint, bx
    mov word ptr oldint+2, es
    mov bx, cs
    mov ds, bx
    mov dx, offset newint09
    mov ax, 2509h
    int 21h
    int 09h
    lea dx, main
    int 27h
    int 20h
    segm ends
    end start
Код делается резидентным, с заменой в таблице векторов прерываний, только вот он не работает.... Пытался отладить таким способом: после строки in al, 60h добавлял
cmp al, 21h
jz line_asd
при нажатии f курсор сдвигался вправо, без этих строк ничего не получается. Пробовал с нажатым шифтом и контролом - тоже ничего. Что я делаю не так?
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
11.10.2014, 16:26
Ответы с готовыми решениями:

Прерывание в си++, отслеживание нажатых клавиш
Доброго времени суток, пишу программу, которая выполняет ряд различных простых задач друг за другом в бесконечном цикле. Задача следующая,...

Прерывание клавиатуры
нужна помощь. есть задание: Поставить в соответствие десятичным цифрам (0 - 9) азбуку, подобную азбуке Морзе (см. таблицу ниже)....

Написать собственное прерывание от клавиатуры
Здравствуйте уважаемые программисты!нужна помощь в выполнении задания "написать собственное прерывание от клавиатуры".в...

3
Клюг
 Аватар для Charles Kludge
7677 / 3192 / 382
Регистрация: 03.05.2011
Сообщений: 8,380
11.10.2014, 18:03
Цитата Сообщение от dmitriy____ Посмотреть сообщение
1) Считываем из порта 60h код клавиши
Цитата Сообщение от dmitriy____ Посмотреть сообщение
Что я делаю не так?
Всё. Перехват int9 и чтение порта 60h неактуально с момента появления XT286, то есть лет 25 уже как.
Дело в том, что с появлением 286+ обработчик int9 вызывает int 15h/ah=4Fh специально для обработки таких ситуаций. Пример обработчика int15h/ah=4fh здесь - там больше выкидывать, чем дописывать. Статус Shft/Ctrl/Alt отбрабатывается, надо просто возвращать сканкод стрелок вместо сканкодов asd/zxc. Талбичка сканкодов.
1
0 / 0 / 0
Регистрация: 11.10.2014
Сообщений: 12
12.10.2014, 09:29  [ТС]
Charles Kludge, спасибо, почитал про 15 прерывание, только вот непонятно, нажатие ctrl/shift и других управляющих клавиш как анализировать, тоже через слово флагов?
Тем временем исправил свой старый код(не работали подпрограммы определения нажатия клавиш одной из линеек - заменены на прямое сравнение; неверно анализировал слово флагов - забыл в каком порядке байты из памяти загружаются). Если кому нужно - вот:
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
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
JUMPS
segm segment para public 'code'
assume cs:segm, ds:segm
org 100h
start: jmp main
oldint dd ?
key db 0
 
newint09 proc far
    ;необходимо проверить слово флагов клавиатуры на нажатие shift, ctrl
    ;если нажат shift, то необходимо опять сравнить скан код с линейкой asd, если попал, то вывести букву, если нет, от вызывать обработчик клавиатуры
    ;нужно получить слово флагов клавиатуры
    sti
    push ax
    push bx
    push dx
    push di
    push es
    in al, 60h
    mov [key], al
    push ds
    mov ax, 0040h
    mov ds, ax
    mov bx, 0017h
    mov ax, word ptr [ds:bx]
    pop bx
    mov ds, bx;восстановим адрес сегмента данных
    ;сначала Lshift, Rshift
    test ax, 0003h
    jnz cmp_asd
    ;теперь Ctrl'ы
    test ax, 5004h
    jnz cmp_zxc
    jmp replacement;проверка на нажатие клавиш одной из линеек и если нужно - подмена на стрелки
    
cmp_asd:;при нажатом шифте
    mov al, [key]
    IRP X,<1eh, 1fh, 20h, 21h, 22h, 23h, 24h, 25h, 26h>
    cmp al, X
    jz print_asd
    endm
    mov al, [key]
    irp x,<2ch, 2dh, 2eh, 2fh, 30h, 31h, 32h>
    cmp al,x
    jz line_zxc
    endm
    jmp ext;
print_asd:;отжать шифт, вызвать стандартный обработчик для печати буквы
    push ds
    mov ax, 0040h
    mov ds, ax
    mov bx, 0017h
    mov ax, word ptr [ds:bx];вроде как получил...
    and ax, 1111111111111100b;
    mov word ptr[ds:bx], ax;
    pop bx
    mov ds, bx;
    jmp ext
cmp_zxc:
    mov al, [key]
    irp x,<2ch, 2dh, 2eh, 2fh, 30h, 31h, 32h>
    cmp al,x
    jz print_zxc
    endm
    ;
    mov al, [key]
    IRP X,<1eh, 1fh, 20h, 21h, 22h, 23h, 24h, 25h, 26h>
    cmp al, X
    jz line_asd
    endm
    jmp ext;
print_zxc:
    push ds
    mov ax, 0040h
    mov ds, ax
    mov bx, 0017h
    mov ax, word ptr [ds:bx]
    and ax, 0100111111111011b
    mov word ptr[ds:bx], ax;
    pop bx
    mov ds, bx;
    jmp ext;
    ;;;;;;;;;;;;;;
    ;если не проработал ни один из вариантов
    ;;;;;;;;;;;;;;
replacement:
    mov al, [key]
    IRP X,<1eh, 1fh, 20h, 21h, 22h, 23h, 24h, 25h, 26h>
    cmp al, X
    jz line_asd
    endm
    irp x,<2ch, 2dh, 2eh, 2fh, 30h, 31h, 32h>
    cmp al,x
    jz line_zxc
    endm
    jmp ext;
line_zxc:
    mov ax, 0040h
    mov es, ax
    mov di, es:[01ch]
    mov ax, 4800h
    mov es:[di], ax
    cmp di, 03ch
    je beg3
    inc di
    inc di
    jmp save4 
    beg3: mov di, 01eh
    save4: mov es:[01ch], di
    jmp end_ret;
line_asd:
    mov ax, 0040h
    mov es, ax
    mov di, es:[01ch]
    mov ax, 4d00h
    mov es:[di], ax
    cmp di, 03ch
    je beg2
    inc di
    inc di
    jmp save2 
    beg2: mov di, 01eh
    save2: mov es:[01ch], di
    jmp end_ret;
end_ret:
    in al, 61h
    mov ah, al
    or al, 80h
    out 61h, al
    mov al, ah
    out 61h, al
    cli
    mov al, 20h
    out 20h, al
    pop es
    pop di
    pop dx
    pop bx
    pop ax
    iret
ext:
    cli
    pop es
    pop di
    pop dx
    pop bx
    pop ax
    jmp cs:[oldint]
 
newint09 endp
;///////////////////////////////////////////////////////
main:
    mov ax, 3509h
    int 21h
    mov word ptr oldint, bx
    mov word ptr oldint+2, es
    mov bx, cs
    mov ds, bx
    mov dx, offset newint09
    mov ax, 2509h
    int 21h
    lea dx, main
    int 27h
    int 20h
    segm ends
    end start
0
Клюг
 Аватар для Charles Kludge
7677 / 3192 / 382
Регистрация: 03.05.2011
Сообщений: 8,380
12.10.2014, 09:45
Цитата Сообщение от dmitriy____ Посмотреть сообщение
только вот непонятно, нажатие ctrl/shift и других управляющих клавиш как анализировать, тоже через слово флагов?
Ну да... Сделано через жопу, как и всё, к чему прикоснулся билли-бой.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
12.10.2014, 09:45
Помогаю со студенческими работами здесь

Прерывание int 16h, ввод с клавиатуры: показать введённый символ
Доброго всем времени суток. У меня есть задача, в которой мне нужно воспользоваться вводом с клавиатуры именно этого самого 16 прерывания....

Как организовать прерывание только цыкла, а не программы из клавиатуры.
Как организовать прерывание только цыкла, а не программы из клавиатуры. Например в программе в диалоговом режиме, пользователь...

Переопределить прерывание таймера 8h, и каждые 5 секунд загонять в буфер клавиатуры букву 'а'
Ребята, помогите. Задали задачку на асме. Необходимо переопределить прерывание таймера 8h, и каждые 5 секунд загонять в буфер клавиатуры...

Зашифровать введенную с клавиатуры строку заменой исходных символов на символы с кодом, большим на три единицы. Провести дешифровку.
помогите мне плизз я дуб....=( :cry: Зашифровать введенную с клавиатуры строку заменой исходных символов на символы с кодом, большим на...

Переназначение клавиш клавиатуры
Есть ли программа, которая позволит повесить на кнопку комбинацию клавиш, например нажимая на &quot;s&quot;, эмулируется нажатие &quot;s +...


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

Или воспользуйтесь поиском по форуму:
4
Ответ Создать тему
Новые блоги и статьи
Символьное дифференцирование
igorrr37 13.02.2026
/ * Логарифм записывается как: (x-2)log(x^2+2) - означает логарифм (x^2+2) по основанию (x-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