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

标签 linux assembly system-calls

我正在尝试学习如何在汇编中使用 linux 64 位系统调用。

我正在编写一些代码来读取键盘并简单地在屏幕上打印按下的键:我正在使用 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 时它不退出

最佳答案

it automatically prints on screen the keys

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

  • 键盘输入打印到屏幕
  • sys_read 将等待,直到按下返回(回车)键

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

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

it doesn't exit when i press esc

文件中存在三个问题:

  1. 据我所知,每当您调用 sys_read 时,您都会读取两个字节 - 这意味着两次击键
  2. sys_read 将等待直到按下返回键(见上文)
  3. 将一个 64 位值与一 block 只有一个(或两个)字节长的内存进行比较。

您应该使用 sys_read 只读取一个字节。那么您应该进行按字节比较而不是 64 位比较:

cmp bl,key

代替:

cmp rbx,key

关于linux - 使用 x64 linux 系统调用(汇编)从键盘读取输入,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24419077/

相关文章:

assembly - 了解汇编语言中的 cmpb 和循环

c - 使用自定义系统调用时出现 undefined reference 错误

linux - 父进程的进程 ID 未显示在 ps-a 命令中

linux -/etc/sudoers 文件有问题但无法访问 root

linux - 如何从文件中提取多行扩展的电子邮件 header

assembly - NASM程序集将输入转换为整数?

assembly - 在程序集中添加有符号数字

c++ cgi app调用其他程序失败

PHP 5.3.2 和 Zend Framework session

linux - 如何自动运行(不同目录)的bash文件作为输入