考虑以下代码
.bss
.lcomm num, 20 /* Reserve 20 bytes for local common storage */
.text
.global _start
_start:
/* read from stdin */
mov r0, $1 /* Move 1 into r0 register for syscall (file descriptor stdout) */
ldr r1, =num /* Load our reserved 20 bytes for the buffer into r1 */
mov r2, $20 /* Set our max input to 20 bytes */
mov r7, #3 /* Load syscall read (3) into r7 */
swi $0 /* Invoke the system call */
/* print to stdout */
mov r0, $1 /* Move 1 into r0 register for syscall (file descriptor stdout) */
ldr r1, =num /* Load our now populated buffer into r1 */
mov r2, $20 /* Set the write output to 20 bytes */
mov r7, #4 /* Load syscall write (4) into r7 */
swi $0 /* Invoke the system call */
/* exit with 0 exit code */
mov r0, $0 /* Set exit code to 0 in register r0 */
mov r7, $1 /* Load syscall number into register r7 (1 for exit) */
swi $0 /* Invoke the system call */
很明显.lcomm num,20只是20个字节,因此将输入字符串的最大大小限制为20个字节。
如何更改此代码以接受任何长度的字符串? (在合理范围内)。
答案 0 :(得分:0)
代码可能不正确:即使write
系统调用以较少的计数返回,您也20
read
个字节,就像标准输入是较小的文件一样。
你的问题不明确。您是否希望在一个系统调用中读取标准输入中的所有可用数据,并将其写入标准输出的一个块中?请注意,这并非总是可行:
标准输入可能是大于可用内存的文件。
标准输入可能是设备或管道,您无法知道在文件结束之前如何读取人工字节。
实际上,从管道读取将一次产生有限的块。您可能需要发出多个系统调用来读取所有输入。
系统调用可能还有其他原因导致失败并需要重新启动,例如,如果信号中断它。查看read
的手册页。
如果要在汇编程序中实现简单的cat
,至少应该实现这些情况。选择一个更大的缓冲区大小,循环直到检测到文件结尾(read
返回0字节计数),并正确处理read
和write
错误和短计数。
标记C
并非无用:您应该编写一个C实现并查看程序集输出以获取灵感。