Вывод сообщения в зависимости от нажатой клавиши - Assembler

Узнай цену своей работы

Формулировка задачи:

При вводе прописных латинских букв (в верхнем регистре) выдавать с новой строки на экран сообщение "Введен символ <X>" ,а при нажатии этих клавиш в комбинации с Alt — сообщение "Нажата комбинация Alt<X>" (<X> — соответствующий ASCII-символ). Выход — Esc.

Решение задачи: «Вывод сообщения в зависимости от нажатой клавиши»

textual
Листинг программы
LOCALS
 
.model small
 
.stack 100h
 
.data
        CrLf            db      0Dh, 0Ah, '$'
        msgSimpleChar   db      'Введен символ '
        SimpleChar      db      ?
                        db      0Dh, 0Ah, '$'
        msgAltChar      db      'Нажата комбинация Alt'
        AltChar         db      ?
                        db      0Dh, 0Ah, '$'
        kbState         db      ?
        kbAlt           equ     08h
        kbCapsLock      equ     40h
        kbRShift        equ     01h
        kbLShift        equ     02h
        kbShift         equ     kbLShift or kbRShift
 
        ScanCodeQ       equ     10h
        ScanCodeP       equ     19h
        ScanCodeA       equ     1Eh
        ScanCodeL       equ     26h
        ScanCodeZ       equ     2Ch
        ScanCodeM       equ     32h
 
        CharsList       db      'QWERTYUIOPASDFGHJKLZXCVBNM'
.code
 
main    proc
        mov     ax,     @data
        mov     ds,     ax
 
@@Loop:
        ;чистаем состояние клавиши Alt
        mov     ah,     02h
        int     16h
        mov     kbState,        al
        ;читаем состояние клавиатуры
        mov     ah,     01h
        int     16h
        jz      @@Loop  ;если нет нажатия клавиш - перейти к началу цикла
        ;чтение нажатой клавиши
        mov     ah,     00h
        int     16h
        ;если нажата клавиша Esc - выйти
        cmp     al,     1Bh
        je      @@Break
        ;проверка, что нажата клавиша символа в верхнем регистре
        ;т.е. нажат или Shift или CapsLock
        mov     bl,     kbState
        and     bl,     kbRShift
        mov     bh,     kbState
        and     bh,     kbLShift
        shr     bh,     1
        or      bl,     bh      ;bl равен 1 если нажат хоть один из Shift
        mov     bh,     kbState
        and     bh,     kbCapsLock
        mov     cl,     6
        shr     bh,     cl
        xor     bl,     bh      ;bl равен 1 если нажато что-то одно: или Shift или CapsLock
        jz      @@Loop
        ;проверка, что нажата клавиша латинского алфавита
        mov     al,     ah
@@1stRow_QP:
        cmp     al,     ScanCodeQ
        jb      @@Loop
        cmp     al,     ScanCodeP
        ja      @@2ndRow_AL
        sub     al,     ScanCodeQ
        jmp     @@ShowMessage
@@2ndRow_AL:
        cmp     al,     ScanCodeA
        jb      @@Loop
        cmp     al,     ScanCodeL
        ja      @@3rdRow_ZM
        sub     al,     ScanCodeA-10
        jmp     @@ShowMessage
@@3rdRow_ZM:
        cmp     al,     ScanCodeZ
        jb      @@Loop
        cmp     al,     ScanCodeM
        ja      @@ShowMessage
        sub     al,     ScanCodeZ-10-9
@@ShowMessage:
        ;определение символа по скан-коду
        mov     bx,     0
        mov     bl,     al
        mov     al,     CharsList[bx]
        ;выбор сообщения, в зависимости от нажатия Alt
        test    kbState,        kbAlt
        jz      @@NoAltPressed
        ;если нажата Alt
        mov     AltChar,        al      ;поместить символ в сообщение
        mov     ah,     09h             ;вывести сообщение
        lea     dx,     msgAltChar
        int     21h
        jmp     @@Loop
@@NoAltPressed:
        ;если не нажата Alt
        mov     SimpleChar,     al      ;поместить символ в сообщение
        mov     ah,     09h             ;вывести сообщение
        lea     dx,     msgSimpleChar
        int     21h
        jmp     @@Loop
 
@@Break:
 
        mov     ax,     4C00h
        int     21h
main    endp
 
end     main

Объяснение кода листинга программы

  1. LOCALS: Определение локальных меток
  2. .model small: Определение модели памяти для программы
  3. .stack 100h: Определение размера стэка
  4. .data: Начало сегмента данных
  5. CrLf: Объявление байтовой переменной с символами возврата каретки и перевода строки
  6. msgSimpleChar: Объявление строки для сообщения Введен символ
  7. SimpleChar: Объявление переменной для символа
  8. msgAltChar: Объявление строки для сообщения Нажата комбинация Alt
  9. AltChar: Объявление переменной для символа
  10. kbState: Объявление переменной для состояния клавиши
  11. kbAlt, kbCapsLock, kbRShift, kbLShift, kbShift: Определение констант для различных клавиш
  12. ScanCodeQ, ScanCodeP, ScanCodeA, ScanCodeL, ScanCodeZ, ScanCodeM: Определение констант для скан-кодов клавиш
  13. CharsList: Объявление строки с латинским алфавитом
  14. .code: Начало сегмента кода
  15. main proc: Начало процедуры main
  16. mov ax, @data; mov ds, ax: Инициализация сегмента данных
  17. @@Loop: Метка начала цикла ... Далее идет описание алгоритма обработки нажатой клавиши, вывода сообщений в зависимости от нажатой клавиши, и завершение программы. Этот код написан на языке Assembler и предназначен для вывода сообщений в зависимости от клавиши, нажатой пользователем.

Оцени полезность:

5   голосов , оценка 4.6 из 5
Похожие ответы