我想让Linux使用sys_read从键盘上敲击1下键,但是sys_read只是等待直到我按enter键。怎么看1击键?这是我的密码:
Mov EAX,3
Mov EBX,0
Mov ECX,Nada
Mov EDX,1
Int 80h
Cmp ECX,49
Je Do_C
Jmp Error我已经尝试过使用BIOS中断,但它失败了(分割错误),我想从键盘捕获数字1到8输入。
发布于 2020-07-16 16:59:20
64位linux中的Syscalls
man syscall的表在这里提供了一个很好的概述:
arch/ABI instruction syscall # retval Notes
──────────────────────────────────────────────────────────────────
i386 int $0x80 eax eax
x86_64 syscall rax rax See below
arch/ABI arg1 arg2 arg3 arg4 arg5 arg6 arg7 Notes
──────────────────────────────────────────────────────────────────
i386 ebx ecx edx esi edi ebp -
x86_64 rdi rsi rdx r10 r8 r9 -我省略了这里不相关的几行。在32位模式下,参数以ebx、ecx等方式传输,syscall数在eax中传输.在64位模式下,这有点不同:所有寄存器现在都是64位宽,因此有一个不同的名称。syscall号仍然在eax中,现在它变成了rax。但是现在参数在rdi、rsi等中传递。此外,这里使用指令syscall而不是int 0x80来触发syscall。
参数的顺序也可以在手册页中读取,这里是man 2 ioctl和man 2 read
int ioctl(int fd, unsigned long request, ...);
ssize_t read(int fd, void *buf, size_t count);在这里,int fd的值在rdi中,第二个参数在rsi中,等等。
如何摆脱等待换线的等待
首先在内存中创建一个termios结构(在.bss部分):
termios:
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然后获取当前终端设置并禁用规范模式:
; Get current settings
mov eax, 16 ; syscall number: SYS_ioctl
mov edi, 0 ; fd: STDIN_FILENO
mov esi, 0x5401 ; request: TCGETS
mov rdx, termios ; request data
syscall
; Modify flags
and byte [c_lflag], 0FDh ; Clear ICANON to disable canonical mode
; Write termios structure back
mov eax, 16 ; syscall number: SYS_ioctl
mov edi, 0 ; fd: STDIN_FILENO
mov esi, 0x5402 ; request: TCSETS
mov rdx, termios ; request data
syscall现在您可以使用sys_read在击键时读取:
mov eax, 0 ; syscall number: SYS_read
mov edi, 0 ; int fd: STDIN_FILENO
mov rsi, buf ; void* buf
mov rdx, len ; size_t count
syscall然后检查rax中的返回值:它包含读取的字符数。
(错误码,例如,如果您在bash中运行./a.out <&-来关闭stdin )。使用strace打印系统调用您的程序的解码跟踪,因此您不需要在玩具实验中实际编写错误处理。
参考资料:
https://stackoverflow.com/questions/62937150
复制相似问题