如何测试以确保只输入一个整数并确保在汇编中输入的长度为 5 个字节或更少?

How do I test to ensure only an integer is entered and ensure length of input is 5 bytes or less in Assembly?

如何测试以确保仅输入整数并确保在以下代码中输入的长度不超过 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

我只想回答问题的 POSIX 系统编程部分,一旦您知道您的程序要做什么,您就可以进行正确的系统调用。使用 gdb 对其进行调试(请参阅 标记 wiki 底部的调试提示),并 strace 跟踪系统调用。

您可能想用 C 编写程序,而不是尝试同时学习 asm 和 Unix 系统调用 API。用 C 写一些东西来测试这个想法,然后用 asm 实现它。 (然后你可以在卡住的时候看看编译器的输出,看看编译器是如何做的。只要你仔细阅读并理解编译器生成的代码是如何工作的,你'仍在学习。我建议使用 -O2-O3 作为 asm 实现的起点进行编译。至少 -O1,绝对不是 -O0。)。


I am trying to understand how to properly control input so that the input beyond 5 bytes is not outputted to the terminal upon exiting of the program.

这只是一个POSIX语义问题,与asm无关。如果您在 C 中进行系统编程,调用 read(2) system call,那将是相同的。您在 asm 中使用 mov eax,3 / int 0x80 调用它,而不是像 C 编译器输出那样 calling glibc 包装器,但它是相同的系统调用。

如果程序退出时 the terminal (tty) 上有未读数据,shell 将在检查输入时读取它。

在 tty 上的交互式 shell 运行ning 中,您 运行 的程序(如 ./a.out/bin/cat)将其标准输入连接到shell 从中获取交互式输入的相同 tty 设备。因此,程序标准输入中的未读数据与 shell 将看到的未读数据相同。

如果您从文件重定向程序的输入,情况就不同了。 (./a.out < my_file.txt)。那么您的程序将不会以 tty 的已经打开的文件描述符开始。它仍然可以 open("/dev/tty")(这是一个 "magic" 符号链接,它总是指控制 tty)并清除在 运行ning 时键入的任何内容。


ensure only an integer is entered and ensure length of input is 5 bytes or less in the following code?

您无法控制输入内容。您可以检测您不喜欢的输入,并打印一条错误消息或您想要执行的任何其他操作。

如果您希望输入的字符在 5 个字节后停止回显到屏幕,您需要 put the tty into raw mode(而不是默认的行缓冲 "cooked" 模式)并执行回显手动,或在 5 个字节后禁用回显。 (不过,后者并不可靠。在禁用 echo 和用户键入第 6 个字节(例如,作为粘贴的一部分)之间存在竞争条件。


回复:编辑

I am just stuck on when more than 5 integer bytes are entered it wont re-prompt as it does when I enter in a character data as it continues to dump extra bytes data to tty.

你破坏了你的程序,因为如果你不喜欢你读到的数字,逻辑仍然是围绕着重新read()输入一个字符而设计的。但是您的 read 调用最多读取 5 个字节。

正常的做法是一个大 read 然后通过遍历缓冲区中的字节来解析整行。所以在 .bss 部分使用大缓冲区(如 1024 字节),并进行 read 系统调用。

不要再次进行 read 系统调用,除非你想提示用户输入另一行文本。

(既然你接受了这个答案,我会指出这个关于在 TTY 上使用 read 的问题的实际答案是 。)

这是对你 low-quality followup question 的回答,当你删除它时我正要 post。

请注意,我说的是 "you can ask for debugging help in a new question",并不是说您应该在一个问题中提出 3 个不同的问题,然后重新 post 您的整个代码几乎没有改变,没有认真尝试解决您自己的问题。将新问题设为 问题仍取决于您。

如果不是我一开始就引导你 post 我可能不会回答它。欢迎来到 Whosebug,我很慷慨,因为你是新手,还不知道什么是好问题。


字符“0”到“9”的常用术语是 "digit",而不是 "integer"。它更具体。

ensure only integers are inputted in the buffer

你不能。如果检测到此类输入,您必须决定要做什么。

Need help creating an array to loop through

您的缓冲区是一个字节数组。

你可以用

之类的东西循环它
    # 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.

ensure characters over the 1024 buffer do not send data to the tty

如果你担心 1024 对这个玩具程序来说不一定足够大,那么使用 select(2)poll(2) 检查是否有更多的输入可以读取而不会阻塞,如果没有't.