Одна вещь, которую вы хотите иметь в виду, заключается в том, что нажатие клавиши не обязательно равняется одному байту. Например, функциональные клавиши могут возвращать до 5 байтов. Этот метод не требует специально выделенного буфера, но концептуально пространство в стеке можно считать буфером.
См. Комментарий ниже edi, 8 должно быть edx , 8
mov edi, 8 ; Size of one QWORD
push rax ; Could be any register, we just need 8 bytes
mov rsi, rsp
xor edi, edi ; Essentially STDIN
mov eax, edi ; SYS_READ
syscall
pop rax ; Bytes
Если вы нажали одну из 96 клавиш из пробела (20H) для тильды (7FH), тогда ваш результат будет возвращен в AL. Однако, если AL = 27 (1BH), то остальные биты (08-3F) будут иметь другие соответствующие данные.
Я использую эту процедуру, чтобы принять одно нажатие клавиши без эха и необходимость нажать клавишу возврата, чтобы принять ввод .
; =============================================================================
; Accept a single key press from operator and return the result that may be
; up to 5 bytes in length.
; LEAVE: RAX = Byte[s] returned by SYS_READ
; -----------------------------------------------------------------------------
%define c_lflag rdx + 12
%define keys rbp + 8
%define MASK ICANON | ECHO
STK_SIZE equ 56 ; Room for 36 byte termios structure
QueryKey:
xor eax, eax
push rax ; This is where result will be stored.
push rbp
mov rbp, rsp
sub rsp, STK_SIZE
push r11 ; Modified by SYSCALL
push rbx
push rdx
push rcx
push rdi
push rsi ; With size of 56, stack is now QWORD aligned
mov edi, eax ; Equivalent to setting EDI to STDOUT
mov esi, TCGETS
lea rdx, [rbp-STK_SIZE] ; Points to TERMIOS buffer on stack
mov al, sys_ioctl
syscall
lea rbx, [c_lflag]
and byte [rbx], ~(MASK)
inc esi ; RSI = TCPUTS
push rsi
mov al, sys_ioctl
push rax
syscall
; Wait for keypress from operator.
lea rsi, [keys] ; Set buffer for input
push rdx
mov edx, 8 ; Read QWORD bytes max
mov al, sys_read
syscall
pop rdx ; Points back to TERMIOS
pop rax
pop rsi ; TCPUTS again
or byte [rbx], MASK
syscall
pop rsi
pop rdi
pop rcx
pop rdx
pop rbx
pop r11
leave
pop rax ; Return up to 8 characters
ret