哪个Linux系统调用我应该用从标准输入读取原始字符? [英] Which Linux system calls should I use to read raw characters from stdin?
问题描述
我想我的口 stdrepl
库FASM学习的目的。我知道,GNU readline库已经做了什么,我试图做的,但我想学习如何写不平凡的程序汇编。
I'm trying to port my stdrepl
library to FASM for learning purposes. I know that the GNU readline library already does what I'm trying to do, but I want to learn how to write non-trivial programs in assembly.
在我的Node.js可以很容易地编写创建一个TTY:
In node.js I can easily create a tty by writing:
var stdin = process.stdin;
stdin.setEncoding("utf8");
stdin.setRawMode(true);
stdin.resume();
我如何实现纯汇编相同的结果。我想在一个循环如下时间从读标准输入
字节长,但是它不返回字节对的,我打了一个键后:
How do I achieve the same results in pure assembly. I tried reading one byte from stdin
at a time in a loop as follows, but it doesn't return the byte right after I hit a key:
oct db ?
mov eax, 3
xor ebx, ebx
mov ecx, oct
mov edx, 1
请注意,数据定义月
不是循环的一部分,所以请不要杀我了点。我知道如何构建一个汇编程序。
Note that the data definition oct
is not a part of the loop, so please don't smite me for that. I know how to structure an assembly program.
推荐答案
很抱歉的延迟(我真的应该登记在这里 - 那将让我通知,对吧?)。正如我所说的,这是基本的和不完善的。一些通常的东西可能被其他地方定义,但我认为你可以弄清楚如何得到它的组装。叫它 - 没有参数 - 而关键是在人
返回。希望这是一些对你有用!
Sorry for the delay (I really should "register" here - that'll get me "notifications", right?). As I said, it's rudimentary and imperfect. Some of the "usual" stuff may be defined elsewhere, but I think you can figure out how to get it to assemble. Just call it - no parameters - and the key is returned in al
. Hope it's some use to you!
;-----------------------------
; ioctl subfunctions
%define TCGETS 0x5401 ; tty-"magic"
%define TCSETS 0x5402
; flags for 'em
%define ICANON 2 ;.Do erase and kill processing.
%define ECHO 8 ;.Enable echo.
struc termios
alignb 4
.c_iflag: resd 1 ; input mode flags
.c_oflag: resd 1 ; output mode flags
.c_cflag: resd 1 ; control mode flags
.c_lflag: resd 1 ; local mode flags
.c_line: resb 1 ; line discipline
.c_cc: resb 19 ; control characters
endstruc
;---------------------------------
getc:
push ebp
mov ebp, esp
sub esp, termios_size ; make a place for current kbd mode
push edx
push ecx
push ebx
mov eax, __NR_ioctl ; get current mode
mov ebx, STDIN
mov ecx, TCGETS
lea edx, [ebp - termios_size]
int 80h
; monkey with it
and dword [ebp - termios_size + termios.c_lflag], ~(ICANON | ECHO)
mov eax, __NR_ioctl
mov ebx, STDIN
mov ecx, TCSETS
lea edx, [ebp - termios_size]
int 80h
xor eax, eax
push eax ; this is the buffer to read into
mov eax, __NR_read
mov ebx, STDIN
mov ecx, esp ; character goes on the stack
mov edx, 1 ; just one
int 80h ; do it
; restore normal kbd mode
or dword [ebp - termios_size + termios.c_lflag], ICANON | ECHO
mov eax, __NR_ioctl
mov ebx, STDIN
mov ecx, TCSETS
lea edx, [ebp - termios_size]
int 80h
pop eax ; get character into al
pop ebx ; restore caller's regs
pop ecx
pop edx
mov esp, ebp ; leave
pop ebp
ret
;-------------------------
这篇关于哪个Linux系统调用我应该用从标准输入读取原始字符?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!