Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Низкоуровневое программирование > Assembler - Ассемблер (FASM, MASM, WASM, NASM, GoASM, Gas, RosAsm, HLA) и не рекомендуем TASM
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 26.05.2016, 15:45   #1
Max00766
Форумчанин
 
Регистрация: 15.11.2015
Сообщений: 151
По умолчанию Заменить стандартный обработчик клавиатуры(вывод скан кодов)

Есть программа которая выводит скан код нажатия \ отпускания клавиши, но она использует прерывание 16h, преподу это не понравилось и он сказал что надо заменить своей процедурой обработки прерывания от клавиатуры. Нужно что бы программа делала все тоже, только не используя 16h.
Помогите, пожалуйста, разобраться с этим, так как сам в ассемблере разбираюсь слабо.
Код:
;TASM, EXE
.model small                      
.386      
 
.data 
mess0   db   13,10,10,' Symbol: $'
mess1   db   13,10,' ---------------'
        db   13,10,' Press..: $'
mess2   db   13,10,' UnPress: $'
 
 
.stack                      
    db  256 dup(?)      
    
    
.code  
start: mov ax,@data        
       mov ds,ax
       lea   dx,mess0        
       call  message         
       xor   ax,ax           
       int   16h             
       cmp   al,13          
       je    exit            
       int   29h            
       xchg  ah,al          
       xor   ah,ah          
       push  ax ax ax       
       lea   dx,mess1        
       call  message         
       pop   ax              
       call  outHex         
       lea   dx,mess2        
       call  message         
       mov   ax,'F0'        
       int   29h             
       shr   ax,8            
       int   29h             
       mov   al,','          
       int   29h             
       pop   ax              
       call  outHex         
       jmp   start           
 
exit: mov  ax,4c00h
      int  21h      
;------------------------------------------------
 
message:                     
       mov   ah,9            
       int   21h             
       ret                   
 
outHex:                      
       shl   ax,8          
       xchg  dx,ax           
       mov   cx,2            
@1:    shld  ax,dx,4         
       rol   dx,4            
       and   al,0Fh          
       cmp   al,0Ah          
       sbb   al,69h          
       das                   
       int   29h             
       loop  @1              
       ret                   
       end start
Max00766 вне форума Ответить с цитированием
Старый 26.05.2016, 16:57   #2
R71MT
Участник клуба
 
Аватар для R71MT
 
Регистрация: 16.06.2011
Сообщений: 1,428
По умолчанию

Max00766, чё сам думаешь по этому поводу?
..или будем ждать готового решения? Читай с порта(60h) и так-же выводи на экран. Благо литературы в гугле хватает. Если что-то конкретное не получается, тогда можно спросить здесь.
Нашедшего выход - затаптывают первым..
R71MT вне форума Ответить с цитированием
Старый 27.05.2016, 10:59   #3
Mikl___
Участник клуба
 
Регистрация: 11.01.2010
Сообщений: 1,139
По умолчанию

R71MT,
вот этого пункта правил не хватало на сайберфорум (сперто с Компьютерного форума Ru.Board )
Цитата:
важное примечание
для тех кто считает, что здесь место халявных исполнений курсовых и лабораторных работ.
тут обычно помогают тем, кто сам хоть что-то пытается понять и сделать, но что-то не понимает, что-то не получается...
ведь ассемблер изучают и задачки на нём дают обычно не менеджерам по продажам и даже не всем физ.-мат. специальностям
вы сами избрали этот путь? вот и идите по нему сами, ножками... с ручками и с головой...

короче, тут не сборище придурков-альтруистов, которым нечего делать и они ждут-не дождутся когда вы их попросите
что-то сделать _за_ вас
если позарез надо и вы даже готовы заплатить, тогда вам в раздел Фриланс
удачи
Mikl___ вне форума Ответить с цитированием
Старый 27.05.2016, 11:28   #4
R71MT
Участник клуба
 
Аватар для R71MT
 
Регистрация: 16.06.2011
Сообщений: 1,428
По умолчанию

Mikl___, хорошо сказано, лучше не придумаешь.
Здесь хоть ТС просит помочь, а в клинических случаях от студентов и этого не дождёшься. Как-будто так и надо: - "написать программу" ..и всё!
Нашедшего выход - затаптывают первым..
R71MT вне форума Ответить с цитированием
Старый 27.05.2016, 13:03   #5
Max00766
Форумчанин
 
Регистрация: 15.11.2015
Сообщений: 151
По умолчанию

Я с помощью людей написал такой код, который вроде бы заменяет стандартный обработчик, можете проверить и сказать что не так?
Код:
.model small            ;модель памяти              
.386      
 
.data 
mess0   db   13,10,10,' Symbol: $'
mess1   db   13,10,' ---------------'
        db   13,10,' Press..: $'
mess2   db   13,10,' UnPress: $'
 
 
.stack                  ;сегмент стека      
    db  256 dup(?)      ;выделение памяти под стек
    
    
.code  
start: mov ax,@data        
       mov ds,ax
       lea   dx,mess0        
       call  message
       cli;запрещаем аппаратные прерывания
       in   al,60h;читаем сканкод
 
       cmp   al,13           ; на выход, если Enter
       je    exit            ;
       int   29h             ; выводим ASC на экран
       xchg  ah,al           ; отправляем SCAN в ASC
       xor   ah,ah           ; очищаем ASC
       push  ax ax ax        ; запиминаем SCAN
       lea   dx,mess1        ;
       call  message         ;
       pop   ax              ;
       call  outHex          ; выводим SCAN нажатия
       lea   dx,mess2        ;
       call  message         ;
       mov   ax,'F0'         ; вставляем F0h
       int   29h             ;
       shr   ax,8            ;
       int   29h             ;
       mov   al,','          ; разделитель
       int   29h             ;
       pop   ax              ;
       call  outHex          ; выводим прицепом SCAN
       jmp   start           ; сл.символ..
 
 
; стандартный выход из обработчика клавиатуры
      in   al,61h
      push ax
      or   al,80h
      out  61h,al
      pop  ax
      out  61h,al
      mov  al,20h
      out  20h,al
      sti;разрешаем прерывания
      
exit: mov  ax,4c00h
      int  21h      ;     
;------------------------------------------------
 
message:                     ;
       mov   ah,9            ;
       int   21h             ;
       ret                   ;
 
outHex:                      ; процедура выводит на экран АХ в HEX
       shl   ax,8            ; AH нам не нужен. Сдвинем в него AL
       xchg  dx,ax           ;
       mov   cx,2            ; разрядов в числе
@1:    shld  ax,dx,4         ;
       rol   dx,4            ;
       and   al,0Fh          ;
       cmp   al,0Ah          ;
       sbb   al,69h          ;
       das                   ;
       int   29h             ;
       loop  @1              ;
       ret                   ;
       end start
Max00766 вне форума Ответить с цитированием
Старый 27.05.2016, 15:04   #6
Max00766
Форумчанин
 
Регистрация: 15.11.2015
Сообщений: 151
По умолчанию

Актуально
Max00766 вне форума Ответить с цитированием
Старый 27.05.2016, 20:31   #7
Max00766
Форумчанин
 
Регистрация: 15.11.2015
Сообщений: 151
По умолчанию

Готовый код, может кому-то пригодится
Код:
.model  tiny;модель памяти
.186
.code
org 100h
;переходим в тектовый режим
start:  mov ax,3
    int 10h
;читаем старый обработчик
    mov ax,3509h
    int 21h
    mov old09s,es
    mov old09o,bx
;ставим свой обработчик
    mov ax,2509h
    lea dx,new09
    int 21h
;зацикливаем программу
    xor ax,ax
@@00:   jnc @@00
;возвращаем обработчик
    mov ax,2509h
    mov dx,old09o
    mov ds,old09s
    int 21h
;востанавливаем сегмент данных
    push    cs
    pop ds
;выводим сообщение
    mov ah,9
    lea dx,dbPres
    int 21h
;сбрасываем буфер клавиатуры, все, что там понажимали и ожидаем ввод
    mov ax,0C01h
    int 21h
;выход
    ret
dbPres  db  10,13,'press any key ...$'
;перевод в символ
dbASCI  db  '  1234567890-=  QWERTYUIOP[]  ASDFGHJKL;"` \ZXCVBNM,./'
szASCI  equ $-dbASCI
    db  128-szASCI dup(' ')
;выводимое сообщение
dbOut   db  'UnPress Simbol:'
dbChar  db  '  ScanCode:'
dwCode  label   word
    db  7 dup(' ')
szOut   equ $-dbOut-2
;адрес старого обработчика
old09   label   dword
old09o  dw  ?
old09s  dw  ?
;свой обработчик
;сохраняем регистры
new09:  pusha
    push    ds
    push    es
    push    cs
    pop ds
;читаем порт
    in  al,60h
;готовим сообщение
    lea si,dbOut
;проверяем нажатие/отпускание
    test    al,80h
    jnz new01
    add si,2
new01:  mov bx,ax
		and bx,7Fh
		
;проверяем нажатие ESC
    cmp al,1
    jnz next
;сбрасываем бесконечный цикл
    mov bp,sp
    or  [bp+24],ax
;получаем символ нажатой клавиши
next:   mov bl,dbASCI[bx]
    mov dbChar,bl
;переводим сканкод в символы
    aam 16
    cmp al,9
    jbe n02
    add al,7
n02:    cmp ah,9
    jbe n03
    add ah,7
n03:    add ax,'00'
    xchg    ah,al
    mov dwCode,ax
;поготавливаем данные к выводу сообщенния
    mov ax,0B800h
    mov es,ax
    mov cx,szOut
    mov ah,0fh
    xor di,di
;выводим сообщение
new04:  lodsb
    stosw
    loop    new04
;вызываем старый обработчик
    pushf
    call    old09
;все востанавливаем
    pop es
    pop ds
    popa
    iret
    end start
Max00766 вне форума Ответить с цитированием
Старый 29.05.2016, 17:46   #8
R71MT
Участник клуба
 
Аватар для R71MT
 
Регистрация: 16.06.2011
Сообщений: 1,428
По умолчанию

Max00766, здесь сам чёрт ногу сломает.. Ты хоть что-нибудь понял в этом коде? Если тебе чисто сдать задание и всё, то это нормально. Если-же (как написАл Mikl___) ты выбрал этот путь, то должен представлять себе, что ты делаешь.

Когда ты нажимаешь на клавишу, INT-09h помещает коды этой клавиши - в буфер клавиатуры. Далее, когда из пользовательской программы вызываются клавиатурные сервисы типа INT-16/21h, они просто читают эту клавишу из буфера клавиатуры, куда её поместил INT-09h.

Если оттрасировать в отладчике вызов INT-16h с AH=0, то можно увидеть, что обработчик этого прерывания сперва настраивается на область памяти (0040:0000h), считавает из клавиатурного буфера клавишу, а потом проверяет, какая функция указана при вызове (в нашем случае AH=0). Далее, в зависимости от номера функции выполняет те или иные действия.

Одним словом, в буфер записывается любое нажатие клавиш вне зависимости от того, вызывались-ли клавиатурные сервисы или нет. Скачай какой-нибудь отладчик реального режима (я остановился на AVPUtil) и поройся в обработчиках прерываний. Это я к тому, что можно вполне обойтись без перехвата прерываний и чтения портов.

Скрин отладчика при входе в функцию(0) INT-16h:
Изображения
Тип файла: jpg dbg.jpg (74.3 Кб, 128 просмотров)
Нашедшего выход - затаптывают первым..
R71MT вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Чем можно заменить стандартный DataGridView в плане дизайна WinForms? Таксист C# (си шарп) 2 08.08.2015 22:33
Ввод последовательности кодов символов с клавиатуры Alexey_Suprun Assembler - Ассемблер (FASM, MASM, WASM, NASM, GoASM, Gas, RosAsm, HLA) и не рекомендуем TASM 0 12.01.2014 14:23
обновление в блоге - Расшифровка скан-кодов клавиш Pblog Обсуждение статей 0 31.05.2011 21:30
Как заменить стандартный вид ползунка (thumb) в компоненте TTackBar своим собственным? SkAndrew Общие вопросы Delphi 2 11.08.2008 16:26