从stdin Assembly ARM11读取(动态)字符串

时间:2015-12-05 20:42:43

标签: assembly arm raspberry-pi

考虑以下代码

.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个字节。

如何更改此代码以接受任何长度的字符串? (在合理范围内)。

1 个答案:

答案 0 :(得分:0)

代码可能不正确:即使write系统调用以较少的计数返回,您也20 read个字节,就像标准输入是较小的文件一样。

你的问题不明确。您是否希望在一个系统调用中读取标准输入中的所有可用数据,并将其写入标准输出的一个块中?请注意,这并非总是可行:

  • 标准输入可能是大于可用内存的文件。

  • 标准输入可能是设备或管道,您无法知道在文件结束之前如何读取人工字节。

  • 实际上,从管道读取将一次产生有限的块。您可能需要发出多个系统调用来读取所有输入。

系统调用可能还有其他原因导致失败并需要重新启动,例如,如果信号中断它。查看read的手册页。

如果要在汇编程序中实现简单的cat,至少应该实现这些情况。选择一个更大的缓冲区大小,循环直到检测到文件结尾(read返回0字节计数),并正确处理readwrite错误和短计数。

标记C并非无用:您应该编写一个C实现并查看程序集输出以获取灵感。