0

我为 IA32 编写了以下汇编脚本。它应该从标准输入读取一个数字,将其递增并将其打印到标准输出,但它的行为不像预期的那样,它不打印任何东西(也许从标准输入的读取不会终止或打印有问题?)

.section .text
    .globl _start

_start:
    movl $3, %eax       # use syscall 3 (read) to read from stdin
    movl $0, %ebx       # reads from stdin (FD 0)
    movl %edi, %ecx    # store input in register %edi
    movl $4, %edx       # read one byte
    int  $0x80      # invoke system call to read from stdin

    incl %edi          # increment the value we got from stdin

    movl $4, %eax       # use syscall 4 (write) to print to screen
    movl $1, %ebx       # print to stdout (FD 1)
    movl %edi, %ecx    # pointer to text to write out
    movl $4, %edx       # length of text to write out (1 byte)
    int  $0x80          # invoke system call to write to stdout

    movl $1, %eax       # use syscall 1 (exit) to exit
    movl $0, %ebx       # error code = 0
    int  $0x80          # invoke system call

你看到错误了吗?对于任何帮助,我提前感谢您,

一切顺利,西蒙

4

1 回答 1

3
movl %edi, %ecx    # store input in register %edi
movl $4, %edx       # read one byte

这部分全错了。您不能将读取的结果存储在寄存器中。实际上所做的是将结果存储在 %edi 中包含的地址中,由于您没有设置它,因此可能是您没有业务存储任何内容的地方。您首先需要在内存中腾出空间来存储字符串。您还在读取四个字节而不是一个。

我会用这样的东西代替它

subl $4, %esp
movl %esp, %ecx
movl $4, %edx

这将为堆栈上的 4 个字节腾出空间,然后使用堆栈顶部作为存储字符串的地址。您还必须修改 write 系统调用的参数以使用此地址。

您必须处理的另一个问题是 stdin 和 stdout 通常处理文本,因此您正在阅读的内容可能是字符串而不是数字,要将其用作数字,您必须将其转换并然后在你写出来之前把它转换回来。

于 2012-09-19T13:30:49.420 回答