Чтение ввода с клавиатуры с помощью системных вызовов x64 linux (сборка)

Я пытаюсь научиться использовать системный вызов Linux 64bits в сборке.

Я писал некоторый код для чтения клавиатуры и просто выводил его на экран нажатыми клавишами: я использую sys_read.

Код:

section .text

global _start

_start:
;write startmsg
mov rax, 1
mov rdi, 1
mov rsi, startmsg
mov rdx, sizestart
syscall
;using sys_read
mov ax, 0
mov rdi, 0
mov rsi, key
mov rdx, 2
syscall
;trying to see if esc is pressed then exit
mov rbx, 0x1b
cmp rbx, key
je _exit

_exit:  
mov rax, 60
mov rdi, 0
syscall

section .bss
key resw 1

section .data
startmsg db 'Press a key', 10
sizestart equ $-startmsg

Теперь происходят две вещи: 1) он автоматически печатает на экране клавиши (D:) 2) он не выходит, когда я нажимаю esc


person vMind    schedule 25.06.2014    source источник


Ответы (1)


он автоматически печатает на экране клавиши

Это настройка по умолчанию в Linux (независимо от языка программирования):

  • Ввод с клавиатуры выводится на экран
  • sys_read будет ждать, пока не будет нажата клавиша возврата (ввода).

Чтобы изменить это поведение, необходимо вызвать функцию tcsetattr() (в C). Вы должны вызвать функцию tcgetattr() перед тем, как сохранить текущие настройки и восстановить их перед выходом из программы.

Если вы хотите использовать системные вызовы напрямую: tcsetattr и tcgetattr используют некоторый sys_ioctl. Чтобы узнать, какой код ioctl() используется, вы можете написать программу на C, выполняющую tcsetattr и tcgetattr, и использовать «strace», чтобы узнать, какие системные вызовы вызываются.

он не выходит, когда я нажимаю esc

В файле три проблемы:

  1. Насколько я правильно понимаю, вы читаете два байта, что означает два нажатия клавиш, всякий раз, когда вы вызываете sys_read
  2. sys_read будет ждать, пока не будет нажата клавиша возврата (см. выше)
  3. Вы сравниваете 64-битное значение с частью памяти длиной всего один (или два) байта (байтов).

Вы должны прочитать только один байт, используя sys_read. Затем вы должны выполнить побайтовое сравнение вместо 64-битного сравнения:

cmp bl,key

вместо:

cmp rbx,key
person Martin Rosenau    schedule 26.06.2014