我应该使用哪些Linux系统调用来读取stdin中的原始字符?

时间:2013-06-08 14:18:15

标签: node.js assembly x86 readline tty

我正在尝试将我的stdrepl库移植到FASM以进行学习。我知道GNU readline库已经完成了我正在尝试做的事情,但我想学习如何在汇编中编写非平凡的程序。

在node.js中,我可以通过写:

轻松创建一个tty
var stdin = process.stdin;
stdin.setEncoding("utf8");
stdin.setRawMode(true);
stdin.resume();

如何在纯装配中获得相同的结果。我尝试在循环中一次从stdin读取一个字节,如下所示,但在我按下一个键后它不会立即返回该字节:

oct db ?

mov eax, 3
xor ebx, ebx
mov ecx, oct
mov edx, 1

请注意,数据定义oct不是循环的一部分,所以请不要打扰我。我知道如何构建汇编程序。

1 个答案:

答案 0 :(得分:1)

抱歉延迟(我真的应该在这里“注册” - 这会“给我”通知“,对吗?)。正如我所说,它是基本的和不完美的。一些“通常”的东西可能在别处定义,但我认为你可以弄清楚如何组装它。只需调用它 - 无参数 - 并在al中返回密钥。希望它对你有用!

;-----------------------------
; 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
;-------------------------

;----------------------------- ; 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 ;-------------------------