【问题标题】:Terminal automatically entering input from program as a command终端自动输入来自程序的输入作为命令
【发布时间】:2020-09-07 06:15:01
【问题描述】:

我正在尝试自学如何在 NASM 上使用 X86 编写程序集。我正在尝试编写一个程序,该程序采用单个整数值并在退出之前将其打印回标准输出。

我的代码:

section .data
        prompt: db "Enter a number: ", 0
        str_length: equ $ - prompt

section .bss
        the_number: resw 1

section .text

global _start

_start:
        mov eax, 4      ; pass sys_write
        mov ebx, 1      ; pass stdout
        mov edx, str_length     ; pass number of bytes for prompt
        mov ecx, prompt     ; pass prompt string
        int 80h
        
        mov eax, 3      ; sys_read
        mov ebx, 0      ; stdin
        mov edx, 1      ; number of bytes
        mov ecx, [the_number]       ; pass input of the_number
        int 80h
        
        mov eax, 4
        mov ebx, 1
        mov edx, 1
        mov ecx, [the_number]
        int 80h
        
        mov eax, 1          ; exit
        mov ebx, 0          ; status 0
        int 80h

从那里我组装nasm -felf -o input.o input.asm 并链接ld -m elf_i386 -o input input.o

我运行一个测试并输入一个整数,当我按下回车键时,程序退出并且 Bash 尝试将输入的数字作为命令执行。我什至echo'd 退出状态并返回 0。

所以这是一种奇怪的行为。

【问题讨论】:

  • 与您的问题无关,但您的提示后面不应有空字节,因为您将长度传递给系统调用。您正在将空字节写入输出设备,这可能会产生奇怪的效果,具体取决于输出设备。

标签: linux assembly terminal nasm


【解决方案1】:

读取调用失败并且不读取任何输入。当您的程序退出时,该输入仍在等待在 TTY(这是该程序的标准输入)上读取,此时 bash 会读取它。

您应该检查系统调用的返回状态。如果系统调用返回时EAX为负数,则为错误码。例如,在本例中,EAX 包含 -14,即 EFAULT(“错误地址”)。

读取失败的原因是您传递了一个无效指针作为缓冲区地址。您需要加载the_number 的地址,而不是它的值。使用mov ecx, the_number

【讨论】:

  • 写系统调用也需要缓冲区的地址,而不是内容。
  • 读取系统调用在检查buf参数的有效性之前等待输入实际上让我感到非常惊讶。在写这个答案之前,我必须编写一个测试程序来确认这一点。
  • 我希望这是因为在将数据复制到用户空间时会自动进行检查,因此事先进行额外的检查将是多余的,并且会减慢地址有效的正常情况。
  • 现在有点解决了。我取出内容值并将其作为读取和最终写入调用的地址。我还将resw 更改为 4。
  • @Nate,是的,我在想,但它必须在准备好写入缓冲区之前对输入进行烹饪,但随后它会使输入保持未读状态,这让我感到困惑。我终于意识到,在将输入复制到用户空间之前,它会将输入煮熟到另一个内核缓冲区中,因此很容易让它在煮熟的缓冲区中保持未读状态。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-09-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-04-05
  • 2010-09-09
相关资源
最近更新 更多