Welcome to WuJiGu Developer Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
1.1k views
in Technique[技术] by (71.8m points)

linux - Assembly: Read integer from stdin, increment it and print to stdout

I coded the following assembly script for IA32. It is supposed to read a number from stdin, increment it and print it to stdout, but it does not behave as expected, it doesn't print anything (maybe the reading from stdin does not terminate or something with the printing is wrong?)

.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

Do you see the error? For any help I thank you in advance,

All the best, Simon

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)
movl %edi, %ecx    # store input in register %edi
movl $4, %edx       # read one byte

This part is all wrong. You can't store the result of read in a register. What that's actually doing is storing the result at the address contained in %edi, which since you haven't set it, is probably somewhere you have no business storing anything. You first need to make room in memory to store the string at. You're also reading four bytes and not one.

I would replace that with something like this

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

This will make room for 4 bytes on the stack, then use the top of the stack as the address to store the string at. You'll also have to modify the arguments for the write syscall to use this address.

Another problem that you'll have to deal with is that stdin and stdout usually deal with text, so what you're reading will probably be a string and not a number, to use it as a number you'll have to convert it and then convert it back before you write it out.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to WuJiGu Developer Q&A Community for programmer and developer-Open, Learning and Share
...