что делает следующий ассемблерный код? Мне нужно написать код, который проверяет, была ли нажата кнопка shift

#assembly #x86-16

#сборка #x86-16

Вопрос:

   PUSH AX
  MOV AH , 12h
  INT 16h
  AND AX,3
  CMP AX,3 ;;; bit 0 = R-shift    bit 1 = L-shift
  JE ClickTwoShift
  POP AX
  

Комментарии:

1. ctyme.com/intr/rb-1773.htm

Ответ №1:

 MOV AH , 12h
INT 16h
  

Эти инструкции вызывают BIOS.Функция GetKeyboardFlags. Он возвращает результат в AX регистре.

 AND AX,3
  

Бит 0 сообщает, нажата ли правая клавиша shift.
Бит 1 сообщает, нажата ли левая клавиша shift.
Добавляя 3, который равен 0000_0000_0000_0011b в двоичной записи, мы сохраняем только те биты, связанные со сдвигом.

 CMP AX,3 ;;; bit 0 = R-shift    bit 1 = L-shift
JE ClickTwoShift
  

Если в этот момент AX регистр равен 3, мы знаем, что были нажаты как левая, так и правая клавиши shift.


Вы можете увидеть, что означают все возвращенные биты, посмотрев наhttp://stanislavs.org/helppc/int_16-12.html


 PUSH AX
MOV AH , 12h
INT 16h
AND AX,3
CMP AX,3 ;;; bit 0 = R-shift    bit 1 = L-shift
JE ClickTwoShift
POP AX
  

Приведенный выше код может иметь проблему с несбалансированным стеком!
Если мы напишем pop ax перед условным переходом к clickTwoShift, коду не потребуется вторая pop ax где-нибудь на пути к ClickTwoShift.

 push    ax
mov     ah, 12h   ; BIOS.GetKeyboardFlags
int     16h       ; -> AX
and     ax, 0003h ; Only keeping 'shift' bits
cmp     ax, 0003h
pop     ax
je      ClickTwoShift