我的程序遇到了烦人的问题。这是代码的一部分
section .bss
input resb 1
section .data
sys_open equ 5
sys_write equ 4
sys_read equ 3
sys_exit equ 1
stdout equ 1
stdin equ 0
一些代码
leerInput:
push ebx
push ecx
mov eax, sys_read
mov ebx, stdin
mov ecx, input
mov edx, 1
int 80h
pop ecx
pop ebx
cmp byte[input],'s'
je avanzarLinea
cmp byte[input], 'e'
jne exitA
jmp avanzarPantalla
现在我要描述试图清楚的问题。首先,程序从控制台中的.txt写入一些行,然后调用leerInput
。如果用户按下键 s ,程序会从.txt再写一行并再次调用leerInput
(直到eof)。与 e 类似但程序写入5行并调用leerInput
...就像命令“more”的小版本一样。如果用户按下另一个键,请调用exitA
并打印错误消息。我的问题是,第一次程序调用{{1}},工作正常,但第二次调用(按 e 或 s 后,程序写入1或5更多line)程序在用户点击任意键之前写入错误消息(跳转到leerInput
)。我认为是与缓冲有关的东西,但是对于汇编我是新的,我发现与冲洗有关的唯一一件事是134系统调用,但不知道是否有用......
答案 0 :(得分:0)
好的尝试,但系统调用134不会帮助你。令人烦恼的问题是sys_read
中的stdin
在按下“enter”之前不会返回。如果讨厌的用户键入的字符多于edx
中允许的字符数,那么多余的字符将留在操作系统的缓冲区中(将其视为“键盘缓冲区”),准备好由下一个sys_read
读取。最简单的修复方法是在缓冲区中允许两个字节,在edx
中允许两个字节 - 一个用于所需的字符,另一个用于命中“enter”时生成的换行符。如果用户输入的内容超过此类,您仍然会遇到麻烦。
如您所料,您想要刷新缓冲区。提供一个单字节“虚拟”缓冲区......
mov edx, length
mov ecx, input
mov ebx, stdin
re_read:
mov eax, sys_read
int 80h
; if the linefeed is in our buffer, we're good
cmp byte [ecx + eax - 1], 10 ; or "LF"
jz goodread:
; else, flush the buffer
mov ecx, dummy
mov edx, 1
; ebx should still be okay
jmp re_read
goodread:
mov edx, length
mov ecx, input
mov ebx, stdin
re_read:
mov eax, sys_read
int 80h
; if the linefeed is in our buffer, we're good
cmp byte [ecx + eax - 1], 10 ; or "LF"
jz goodread:
; else, flush the buffer
mov ecx, dummy
mov edx, 1
; ebx should still be okay
jmp re_read
goodread:
这样的事情。也可以在只有一个键后使用位并使返回,但它更复杂。