linux - 如何“静默”地从 Linux 上的终端获取用户输入?
问题描述
我需要让用户输入跳过其中的每一秒辅音。所以每个第二个辅音不应该被打印出来(不仅仅是在按下 Enter 后在某些过程中删除)。
我从我的老师那里得到了一个汇编语言的任务。目前我在 Linux 上使用 NASM 并希望坚持下去。
问题是我需要“重载”用户输入中断,并且在其中我应该能够处理该输入(每隔一个辅音跳过一次)。我已经搜索了网络并没有找到任何合适的答案。不是如何在缓冲和打印出来之前“捕获”用户输入,也不是在终端不打印的情况下读取单个字符的方法。
我想看一个替换(或修改)标准输入中断系统调用的例子。那将是理想的情况。
第二种选择是让您自己的“处理程序”类型一个接一个地获取每个字符而不回显它,而不是处理诸如 Backspace 和 Enter 我自己之类的事情。就像getch()
在 Windows C 中一样。(或 0x16 BIOS 中断)。
解决方案
这是我用来检索单个击键的示例。请记住,功能键、箭头和其他,如 HOME、PGDN 等返回超过一个字节,因此我最多读取 8 个字节,因此输入缓冲区中剩余的内容不会成为下一次写入的工件。该片段被设计为对以下内容的响应系统;
继续 [是/否]
调用进程将读取 AL 中返回的字符。如果它是 0x1b (27 dec / ESC),那么我们知道它是扩展键之一。例如,F1 将在 EAX 中返回 0x504f1b。
USE64
sys_read equ 0
sys_write equ 1
sys_ioctl equ 16
%define ICANON 2
%define ECHO 8
%define TCGETS 0x5401
%define TCPUTS 0X5402
section .text
; =============================================================================
; 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 STDIN
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
NOTE: The code you need could go here
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
推荐阅读
- javascript - 在 chrome 扩展中获取当前选项卡的登录用户详细信息
- android - 使用 Unity3D 构建 APK 时的 PUP.HighConfidence
- c# - INotifyPropertyChanged 时调用函数 - UWP c#
- java - 无法访问的代码编译没有错误 - 如何?
- git - 当我在主分支上时从不同的分支拉出会发生什么
- apache - Apache Tomcat 9_M9 或 9_M25 高 CPU
- mysql - select with window function (dense_rank()) in SparkSQL
- node.js - PM2 无法通过 docker 使用 esm
- confluence - Confluence wiki format put new paragraph
- database - 用于用户聊天的 Cassandra 表设计