### Author Topic: Printing long number  (Read 3987 times)

#### mk8

• Jr. Member
• Posts: 5
##### Printing long number
« on: May 03, 2014, 04:53:53 PM »
Hi, this is my second topic here, I try to learn a bit of nasm, and got some new issues ;p
My goal is to print any number, so I  thought to divide by 10 number until result isn't 0, and push remainder on stack. Than I wanted to print all from stack, but I am not sure how to find out how many values I have on stack, so when I need to stop `pop` - anyway It doesn't work.

Code: [Select]
`section .text    global _start_start:  mov eax, 12345  intoascii:    cmp eax, 0    je done    mov ebx, 10 ; inside loop..mhm(?)    div ebx     ; i hope result eax/abx is in eax and remainder is in edx    push edx    ; push remainder on stack    jmp intoascii  done:xor esi,esiprint:cmp esi, 5 ; len[12345], every digit from stackje endprint  mov eax, 4  mov ebx, 1  mov ecx, 65  pop ecx  add ecx, 30h  ;int to ascii number  mov [temp], ecx  mov ecx, temp  mov edx, 1  int 80h  inc esi  jmp printendprint:  mov eax, 1  mov ebx, 0  int 80hsection .datasegment .bsstemp resb 1`
May someone look, and say what should I add/change.
Thanks!

#### Frank Kotler

• NASM Developer
• Hero Member
• Posts: 2601
• Country:
##### Re: Printing long number
« Reply #1 on: May 03, 2014, 07:25:18 PM »
Hi mk8,

You're on the right track. (one of several ways to do this) There are a couple of ways to know when to stop "pop"ing. One way would be to "push" some "guard value" first (anything but 0..9 would do) and watch for it as you "pop". An even more obvious way would be to count 'em...

There's another little issue that may be screwing you up.  "div ebx" calculates "edx:eax/ebx", not just "eax/ebx". We might want a 32-bit by 32-bit divide, but that's not what the instruction does, it's a 64-bit by 32ibit divide. This "bug" bites almost every beginner - it's almost a "rite of passage". If edx >= ebx, the quotient won't fit in eax, causing an exception that will crash your program. If you had added '0' to edx before pushing it, you might run into this. Since you add '0' later, it just gives wrong results (almost "worse", actually). We need to zero edx before the "div" every time through the loop.

Here's your code with a couple of minor changes...
Code: [Select]
`section .text    global _start_start:  mov eax, 12345  xor esi, esi ; digit counter  ; could set ebx here and leave it, too  intoascii:    cmp eax, 0    je done    mov ebx, 10 ; inside loop..mhm(?)    ; could do it outside the loop, but this is okay    xor edx, edx ; this needs to be inside the loop!    div ebx     ; i hope result eax/abx is in eax and remainder is in edx    ; close. edx:eax/ebx    push edx    ; push remainder on stack    inc esi ; count the digit    jmp intoascii  done:; xor esi,esiprint: ; this would be okay if we know we've got 5 digits;cmp esi, 5 ; len[12345], every digit from stack;je endprint  mov eax, 4  mov ebx, 1  mov ecx, 65 ; ?  pop ecx  add ecx, 30h  ;int to ascii number; you're putting 4 bytes in a one-byte variable;  mov [temp], ecx  mov [temp], cl  mov ecx, temp  mov edx, 1  int 80h;  inc esi;  jmp print  dec esi  jnz printendprint:  mov eax, 1  mov ebx, 0  int 80hsection .datasegment .bsstemp resb 1`
That's untested, but I think it'll work. Don't hesitate to fiddle with it and try different things. If the number is 0, you probably want to print '0' rather than ignore it entirely. Just move the test for eax=0 a little later in the loop. An alternative to pushing/popping remainders to get 'em in the right order is to put 'em in the buffer (you'll need a buffer big enough) from the "end" and work back toward the "beginning". This may not get you all the way to the beginning before you run out of digits, so you'll need to keep track of the "print position" and the count. Or you can pad the buffer with spaces - "right justified" numbers look nice if you're printing a column of numbers, if you're printing it "in line" you probably don't want the spaces. Make it "work" first, you've got the rest of your life to make it "elegant".

(after looking again at the above code, I've got a bug in it. If esi is zero, "dec esi" is going to loop for a long time! You probably want to print at least one digit anyway. See if you can fix it.)

Best,
Frank

#### mk8

• Jr. Member
• Posts: 5
##### Re: Printing long number
« Reply #2 on: May 03, 2014, 08:05:59 PM »
Thank you Frank for your reply, its a second one which helped me with solving problem and also give a lot of good essential content
« Last Edit: May 03, 2014, 08:09:09 PM by mk8 »