如何测试以确保只输入一个整数并确保在汇编中输入的长度为 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 对其进行调试(请参阅 x86 标记 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 编译器输出那样 call
ing 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.
如何测试以确保仅输入整数并确保在以下代码中输入的长度不超过 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 对其进行调试(请参阅 x86 标记 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 编译器输出那样 call
ing 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.