0

I wrote an Assembly program (x86_64 Linux NASM) that prints an integer to console, based in the algorithm suggested my the comments in this post, which is basically this:

divide number x by 10, giving quotient q and remainder r
emit r
if q is not zero, set x = q and repeat

All works just fine under the following script:

section .bss
        integer resb 100        ; it will hold the EOL
        intAddress resb 8       ; the offset

section .text

        global _start:

_start:

        mov rax, 567
        call _printProc

        mov rax, 60
        mov rdi, 0
        syscall


_printProc: ; here goes the algorithm described above.

After compiling it, the number 567 gets printed on the screen (console).

But if I try to do the same but allowing the user to input the number to be printed as integer I don't get what expected. Well, to do this I made the following changes (the algorithm stays the same):

section .bss
        integer resb 100        ; it will hold the EOL
        intAddress resb 8       ; the offset
        number resb 100

section .text

        global _start:

_start:

        ; getting user input
        mov rax, 0
        mov rdi, 0
        mov rsi, number
        mov rdx, 100
        syscall

        mov rax, [number]       ; passing the content at address number into rax
        call _printProc

        mov rax, 60
        mov rdi, 0
        syscall


_printProc: ; here goes the algorithm described above.

But in this case if I type 567 I get 171390517. In fact, if I type

0, I get 2608
1, I get 2609
2, I get 2610

and so on.

I'd appreciate if some of you have an idea about what is the problem in the second case and how could be fixed.

6
  • 1
    For input you need to convert from text to number (the reverse of the output conversion). For 0 input you get 2608 because your input is the ascii code of 0 which is 48 followed by a line feed with code 10, and that gives 48+10*256=2608 in little endian. Commented May 8, 2017 at 22:41
  • @Jester So in that case I would have to subtract 48 (ASCII code for 0) from the remainder. Is that correct? Am I missing something else? Commented May 8, 2017 at 22:50
  • 1
    Yes, and for multiple digits you of course need to scale by the appropriate power of 10, and obviously ignore the line feed. You don't do this during the output, it's an input conversion there is no "remainder". Commented May 8, 2017 at 22:56
  • @Jester I'm quite new on Assembly so I'd like to get this about multiple digits correctly. From what you said I deduced that the input by the user is ''taken'' one byte (digit) at a time (maybe a somewhat stupid question. Now I'm thinking how I output the number: digit by digit). So for instance if the user input 345, he indeed input first 51 (ASCII for 3) then 52 and finally 53. So at memory intAddress I hold the 51, at intAddress + 1 we have 52 and intAddress + 3 the 53. (my comment is too long so I write below as well). Commented May 8, 2017 at 23:14
  • 2
    The usual trick is to multiply the working value by 10 then add the new digit. Repeat as long as you have digits. E.g. you will have ((51-48)*10+(52-48))*10+(53-48) Commented May 8, 2017 at 23:18

1 Answer 1

1

what happends when you call this

    ; getting user input
    mov rax, 0
    mov rdi, 0
    mov rsi, number
    mov rdx, 100
    syscall

is, that your entry ( e.g. "1004") is written to the memory at "number", character per character. Now you have the exact opposite problem you intended to solve: "how to convert an ASCII string into binary value"

the algorithm for this new problem could look like this:

(assuming char_ptr points to the string)
result = 0;
while ( *char_ptr is a digit )
    result *= 10;
    result += *char_ptr - '0' ;
    char_ptr++;
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.