AFO*_*OEK 1 linux assembly x86-64 nasm tty
我想让 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
Run Code Online (Sandbox Code Playgroud)
我已经尝试使用 BIOS 中断但它失败了(分段错误),我想从键盘捕获数字 1 到 8 输入。
来自的表格在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 -
Run Code Online (Sandbox Code Playgroud)
我省略了此处不相关的行。在 32 位模式下,参数在等中传递eax, ecx系统调用号在 中eax。在 64 位模式下有点不同:所有寄存器现在都是 64 位宽,因此具有不同的名称。系统调用号仍在 中eax,现在变为rax. 但是现在传入了参数rdi, rsi等等。另外,syscall这里使用的是指令,而不是int 0x80触发系统调用。
参数的顺序也可以在手册页中阅读,这里man 2 ioctl和man 2 read:
int ioctl(int fd, unsigned long request, ...);
ssize_t read(int fd, void *buf, size_t count);
Run Code Online (Sandbox Code Playgroud)
所以这里的值int fd是 in rdi,第二个参数 inrsi等。
首先termios在内存中创建一个结构(在.bss节中):
termios:
c_iflag rd 1 ; input mode flags
c_oflag rd 1 ; output mode flags
c_cflag rd 1 ; control mode flags
c_lflag rd 1 ; local mode flags
c_line rb 1 ; line discipline
c_cc rb 19 ; control characters
Run Code Online (Sandbox Code Playgroud)
然后获取当前终端设置并禁用规范模式:
; 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_cflag], $FD ; 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
Run Code Online (Sandbox Code Playgroud)
现在您可以使用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
Run Code Online (Sandbox Code Playgroud)
然后检查中的返回值rax:它包含读取的字符数。
参考:
| 归档时间: |
|
| 查看次数: |
439 次 |
| 最近记录: |