使用x64 linux系统调用(汇编)从键盘读取输入

时间:2014-06-25 21:40:52

标签: linux assembly system-calls

我试图学习如何在汇编中使用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时它不会退出

1 个答案:

答案 0 :(得分:1)

  

它会自动在屏幕上打印按键

这是Linux中的默认设置(独立于编程语言):

  • 键盘输入打印在屏幕上
  • sys_read将一直等到按下return(enter)键

要更改此行为,必须调用tcsetattr()函数(在C中)。你应该先调用tcgetattr()函数来存储当前设置并在离开程序之前恢复它们。

如果要直接使用系统调用:tcsetattr和tcgetattr都使用一些sys_ioctl。要找出使用哪个ioctl()代码,您可以编写一个执行tcsetattr和tcgetattr的C程序并使用" strace"找出被调用的系统调用。

  

按esc时它不会退出

文件中有三个问题:

  1. 据我所知,无论何时调用sys_read
  2. ,都会读取两个字节 - 这意味着两次击键
  3. sys_read将一直等到按下返回键(见上文)
  4. 将64位值与只有一(或两)个字节的内存进行比较。
  5. 您应该使用sys_read只读取一个字节。然后你应该进行逐字节比较而不是64位比较:

    cmp bl,key
    

    而不是:

    cmp rbx,key