如何测试以确保只输入一个整数并确保输入的长度在以下代码中是5个字节或更少?
我试图了解如何正确控制输入,以便在退出程序时不会将超过5个字节的输入输出到终端。
此外,我如何测试以确保只输入一个字符串,最后在最后一个场景中,只输入一个双精度数?
***根据x82和Peter C的指导更新了代码。我做了一些C disas,并且能够修改下面的原始代码。它仍然有一些缺陷,但你们都有很多帮助!当我输入超过5个整数字节时,我只是停留在它不会重新提示,因为它在输入字符数据时会继续将额外的字节数据转储到tty。
SECTION .data ; initialized data section
promptInput db 'Enter Number: ', 0
lenPromptInput equ $ - promptInput
displayInput db 'Data Entered: ', 0
lenDisplayInput equ $ - lenDisplayInput
SECTION .bss ; uninitialized data section
number resb 1024 ; allocate 1024 bytes for number variable
SECTION .text ; code section
global _start ; linker entry point
_start:
nop ; used for debugging
Read:
mov eax, 4 ; specify sys_write call
mov ebx, 1 ; specify stdout file descriptor
mov ecx, promptInput ; display promptInput
mov edx, lenPromptInput ; length of promptInput
int 0x80 ; call sys_write
mov eax, 3 ; specify sys_read call
mov ebx, 0 ; specify stdin file descriptor
mov ecx, number ; pass address of the buffer to read to
mov edx, 1024 ; specify sys_read to read 1024 bytes stdin
int 0x80 ; call sys_read
cmp eax, 0 ; examine sys_read return value in eax
je Exit ; je if end of file
cmp byte [number], 0x30 ; test input against numeric 0
jb Read ; jb if below 0 in ASCII chart
cmp byte [number], 0x39 ; test input against numeric 9
ja Read ; ja if above 9 in ASCII chart
Write:
mov eax, 4 ; specify sys_write call
mov ebx, 1 ; specify stdout file descriptor
mov ecx, displayInput ; display displayInput
mov edx, lenDisplayInput ; length of displayInput
int 0x80 ; call sys_write
mov eax, 4 ; specify sys_write call
mov ebx, 1 ; specify stdout file descriptor
mov ecx, number ; pass address of the number to write
mov edx, 5 ; pass number of numbers to write
int 0x80 ; call sys_write
Exit:
mov eax, 1 ; specific sys_exit call
mov ebx, 0 ; return code 0 to OS
int 0x80 ; call sys_exit
答案 0 :(得分:0)
我只是回答问题的POSIX系统编程部分,一旦你知道你希望你的程序做什么,就可以让你做出正确的系统调用。使用gdb对其进行调试(请参阅x86标记wiki的底部以获取调试提示),并使用strace
来跟踪系统调用。
您可能希望用C编写程序,而不是尝试同时学习asm和Unix系统调用API。用C语言写一些东西来测试这个想法,然后在asm中实现它。 (然后,当你遇到困难时,你可以查看编译器输出,看看编译器是如何做的。只要你仔细阅读并理解编译器生成的代码如何工作,你仍然在学习我建议使用-O2
或-O3
作为asm实现的起点进行编译。至少-O1
,绝对不是-O0
。)。
我试图了解如何正确控制输入,以便在退出程序时不会将超过5个字节的输入输出到终端。
这只是一个POSIX语义问题,与asm无关。如果你在C中进行系统编程,调用read(2)
system call,情况就会一样。你用mov eax,3
/ int 0x80
在asm中调用它,而不是像{C编译器输出那样call
glibc包装器,但它是相同的系统调用。
如果程序退出时the terminal (tty)上有未读数据,shell会在检查输入时读取它。
在tty上运行的交互式shell中,您运行的程序(如./a.out
或/bin/cat
)将其stdin连接到shell从中获取交互式输入的相同tty设备。因此,程序的stdin上的未读数据与shell将看到的未读数据相同。
如果您从文件重定向程序的输入,情况会有所不同。 (./a.out < my_file.txt
)。然后你的程序将不会以tty的已打开文件描述符开头。它仍然可以open("/dev/tty")
(这是一个“神奇的”符号链接,总是指控制tty)并清空在运行时输入的任何内容。
确保只输入一个整数,并确保输入长度为5个字节或更少,在以下代码中?
您无法控制输入内容。您可以检测您不喜欢的输入,并打印错误消息或您想要做的任何其他事情。
如果您希望输入字符在5个字节后停止回显到屏幕,则需要put the tty into raw mode(而不是默认的行缓冲“熟”模式)并手动执行回显,或禁用5个字节后回显。 (但后者不可靠。在禁用回声和用户输入第6个字节之间存在竞争条件(例如作为粘贴的一部分)。
当我输入超过5个整数字节时,我只是坚持它不会像我输入字符数据那样重新提示,因为它继续将额外的字节数据转储到tty。
你打破了你的程序,因为如果你不喜欢你读过的数字,那么逻辑仍然围绕着重新read()
一个字符来设计。但是您的read
调用最多可读取5个字节。
正常的做法是一个大read
,然后通过循环缓冲区中的字节来解析整行。因此,在.bss
部分使用大缓冲区(如1024字节),并进行read
系统调用。
除非您想提示用户输入另一行文字,否则不要进行另一次read
系统调用。
答案 1 :(得分:0)
(由于您接受了此答案,我们会指出在TTY上使用read
这个问题的实际答案是my other answer on this question。)
以下是您删除时我要发布的low-quality followup question的答案。
请注意,我说'#34;你可以在一个新问题中请求调试帮助&#34;而不是你应该在一个问题中提出3个不同的问题,并重新发布你的整个代码几乎没有改变,没有认真尝试解决你自己的问题。您仍然可以将新问题作为一个好的问题。
如果我没有引导你发布它,我可能不会回答它。欢迎来到StackOverflow,我很慷慨,因为你很新,不知道什么是一个好问题。
角色的常用术语&#39; 0&#39;通过&#39; 9&#39;是&#34;数字&#34;,不是&#34;整数&#34;。它更加具体。
确保只在缓冲区中输入整数
你不能。如果检测到这样的输入,你必须决定你想做什么。
需要帮助创建一个循环遍历的数组
你的缓冲区是一个字节数组。
你可以用
之类的东西循环它 # eax has the return value from the read system call, which you've checked is strictly greater than 0
mov esi, number ; start pointer
scan_buffer:
movzx edx, byte [esi]
# do something with the character in dl / edx
...
inc esi ; move to the next character
dec eax
jnz scan_buffer ; loop n times, where n = number of characters read by the system call.
确保1024缓冲区上的字符不发送数据到tty
如果您担心1024对于此玩具计划来说不一定足够大,请使用select(2)
或poll(2)
检查是否还有更多输入如果没有阻止,请不要阻止地阅读。