汇编:从stdin读取整数,递增并打印到stdout

时间:2012-09-19 13:15:39

标签: linux assembly x86 ia-32

我为IA32编写了以下汇编脚本。它应该从stdin中读取一个数字,增加它并将其打印到stdout,但是它没有按预期运行,它不会打印任何东西(也许从stdin读取不会终止或打印出错的东西?)

.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

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

一切顺利, 西蒙

1 个答案:

答案 0 :(得分: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 syscall的参数以使用此地址。

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