从STDIN的汇编字节直接读入寄存器

问题描述 投票:0回答:1

在x64 NASM中,如果我想从STDIN读取一个字符到8位寄存器中,我知道的唯一方法是:

xor rax, rax
xor rdi, rdi
mov rsi, buffer
mov rdx, 1
syscall
mov al, byte [buffer]

是否可以在不使用缓冲区的情况下将字符直接读取到寄存器中? (我正在使用Ubuntu 18.04)

nasm stdin cpu-registers
1个回答
0
投票

您要记住的一件事是按键不一定等于一个字节。例如,功能键最多可以返回5个字节。此方法不需要专门分配的缓冲区,但是从概念上讲,堆栈上的空间可以视为缓冲区。

    mov     edi, 8                ; Size of one QWORD
    push    rax                   ; Could be any register, we just need 8 bytes
    mov     rsi, rsp
    xor     edi, edi              ; Essentially STDIN
    mov     eax, edi              ; SYS_READ
    syscall
    pop     rax                   ; Bytes

如果您从空格(20H)按96个键之一到波浪号(7FH),则结果将在AL中返回。但是,如果AL = 27(1BH),则其余位(08-3F)将具有其他相关数据。

我使用此过程来接受没有回声的单个击键,并且需要按回车键才能接受输入。

; ================================================== ==========================;接受操作员的一次按键操作,然后返回可能是;长度最多5个字节。;离开:RAX = SYS_READ返回的字节; -------------------------------------------------- ---------------------------%定义c_lflag rdx + 12%定义键的rbp + 8%定义面膜ICANON |回声STK_SIZE等于56; 36字节termios结构的空间QueryKey:异或推手;这是存储结果的位置。推送RBPmov rbp,rspsub rsp,STK_SIZE推r11;由SYSCALL修改推rbx推rdx推送rcx推RDI推rsi;现在,堆栈大小为56,QWORD已对齐mov edi,eax;等效于将EDI设置为STDOUTmov esi,TCGETSlea rdx,[rbp-STK_SIZE];指向堆栈上的TERMIOS缓冲区mov,sys_ioctl系统调用lea rbx,[c_lflag]和字节[rbx],〜(MASK)inc esi; RSI = TCPUTS推RSImov,sys_ioctl推拉系统调用;等待操作员按键。lea rsi,[键];设置输入缓冲区推rdxmov edx,8;最多读取QWORD字节mov,sys_read系统调用流行rdx;指向TERMIOS流行风波普西;再次尝试或字节[rbx],掩码系统调用流行音乐流行音乐流行rcx流行rdx流行rbx流行音乐r11离开流行流行;最多返回8个字符退回
© www.soinside.com 2019 - 2024. All rights reserved.