The MASM Forum Archive 2004 to 2012

Miscellaneous Forums => 16 bit DOS Programming => Topic started by: PinoyProgramador on November 18, 2005, 12:06:12 PM

Title: Converting decimal into String Problem
Post by: PinoyProgramador on November 18, 2005, 12:06:12 PM
Hey guys im having a trouble with converting decimal to string. Im out of ideas again. Maybe coz im a total newb in assembly. Im out of registers to use maybe becoz i really dont know wht they are for. Heres the code i came up with.

        org 100h

        mov ax, 000Dh ;Integer to convert to string ( ax == 11 )
        mov dx, buff ; Should be the string where the converted decimal will be stored
        call intToString ; Convert 11 to String '11' and put it in DX which is pointing to buff variable
        call printString ; Pring value of DX
        call getch

        mov ax, 4C00h
        int 21h

buff db 8 dup( 24h )

;===================================:
;PRINTSTRING(). Print String        :
;===================================:
printString:
        mov ax, 0900h
        int 21h
        ret


;===============================
;intToString() Convert Integer :
;===============================
intToString:                   
        xor si, si             
        mov cx, ax             
        push ax
  stiLoop:                     
        mov bl, 0Ah             
        div bl                 
        add al, '0'             
        inc si
        mov dx, buff
        mov [dx+si], ax ; not working

;This is the algorithm for this function
        ;1.  asval = value % 10
        ;2. char = asval + '0' 
        ;3.  value /= 10


;===================================:
;GETCH(). Wait for key press        :
;===================================:
getch:
        mov ax, 0700h
        int 21h
        ret

Title: Re: Converting decimal into String Problem
Post by: sinsi on November 18, 2005, 12:36:09 PM
        mov dx, buff
        mov [dx+si], ax ; not working

in dos (16-bit) you can't use dx
you must use bx...so
        mov bx, buff
        mov [bx+si], ax

also i think you are only getting al with one div, not ax
Title: Re: Converting decimal into String Problem
Post by: PinoyProgramador on November 18, 2005, 12:45:34 PM
Ok tnks. Ill try do it with BX.
Title: Re: Converting decimal into String Problem
Post by: PinoyProgramador on November 18, 2005, 01:37:46 PM
I got it working but. The output is reversed. What would be the best way to do so that the outputing will be in the other way around?

for decimal 100 the out put is 001


        org 100h

Main:
        ;Integer to convert to string
        mov ax, 100d
        mov dx, buff
        call intToString
        call printString
        ;call getch

        mov ax, 4C00h
        int 21h

buff db 8 dup( 24h )

;===================================:
;PRINTSTRING(). Print String        :
;===================================:
printString:
        mov ax, 0900h
        int 21h
        ret


;================================
;intToString() Convert Integer  :
;in DIV,                        :
;ah = remainder , al = qoutient :
;================================

intToString:
        xor si, si

  stiLoop:
        mov bl, 10d
        div bl

        add ah, '0'
        mov bx, dx
        mov byte [bx+si], ah ; This should output at the supposed to be output len and not at index 0 so itll be in the right order for outputting
        inc si

        mov ah, 00h
        cmp ax, 01h
        jl itsEnd
        jmp stiLoop

  itsEnd:
        ret

        ;Function Algo
        ;1.  asval = value % 10
        ;2. char = asval + '0' 
        ;3.  value /= 10


;===================================:
;GETCH(). Wait for key press        :
;===================================:
getch:
        mov ax, 0700h
        int 21h
        ret
Title: Re: Converting decimal into String Problem
Post by: PinoyProgramador on November 18, 2005, 03:23:34 PM
I tried reversing the output. But the program just exits whenever i run it. Any1 know whts wrong with the revrsing part of my code?


        org 100h

Main:
        ;Integer to convert to string
        mov ax, 100d
        mov dx, buff
        call intToString
        call printString
        call getch

        mov ax, 4C00h
        int 21h

buff db 8 dup( 24h )

;===================================:
;PRINTSTRING(). Print String        :
;===================================:
printString:
        mov ax, 0900h
        int 21h
        ret


;================================
;intToString() Convert Integer  :
;in DIV,                        :
;ah = remainder , al = qoutient :
;================================

intToString:
        xor si, si

  stiLoop:
        mov bl, 10d
        div bl

        add ah, '0'
        mov bx, dx
        mov byte [bx+si], ah
        inc si

        mov ah, 00h
        cmp ax, 01h
        jl reversing
        jmp stiLoop

  ;The problem starts here !!
  reversing:
        push 00h

        mov ax, si
        mov bl, 02h
        div bl

        mov cl, al
        mov ch, 00h

    reverse:
        mov ah, byte [bx+si]

        dec si
        pop bx
        push si
        mov si, bx

        mov al, byte [bx+si]
        mov byte [bx+si], ah

        inc si
        pop bx
        push si
        mov si, bx

        mov byte [bx+si], al

        cmp si, cx
        je endits
        jmp reverse

  endits:
        ret

        ;Function Algo
        ;1.  asval = value % 10
        ;2. char = asval + '0' 
        ;3.  value /= 10


;===================================:
;GETCH(). Wait for key press        :
;===================================:
getch:
        mov ax, 0700h
        int 21h
        ret
Title: Re: Converting decimal into String Problem
Post by: MichaelW on November 18, 2005, 04:28:42 PM
One common method of reversing the digits would be to push all of them onto the stack and then pop all of them off of the stack. Because of the way the stack operates, the digits would come off in reverse order. The conversion routine could push the digits as they are generated, and then in a separate loop pop them off of the stack and place them in the buffer.

Title: Re: Converting decimal into String Problem
Post by: PinoyProgramador on November 18, 2005, 11:03:02 PM
MikieW

The sounds very simple i cant beliv i never thought of that. Thnk you very much.  :bg
Title: Re: Converting decimal into String Problem
Post by: PinoyProgramador on November 19, 2005, 03:05:59 AM
Not as simple as i thought. Took me more than an hour. Well im a noob. For those who may have the same problem in the future here is the solution.


        org 100h

Main:
        ;Integer to convert to string
        mov ax, 213d ;213 is the value im trying to print
        mov dx, buff
        call intToString
        call printString
        call getch

        mov ax, 4C00h
        int 21h

buff db 5 dup( 24h )

;===================================:
;PRINTSTRING(). Print String        :
;===================================:
printString:
        mov ax, 0900h
        int 21h
        ret


;================================
;intToString() Convert Integer  :
;in DIV,                        :
;ah = remainder , al = qoutient :
;================================

intToString:
        xor si, si

  stiLoop:
        mov bl, 10d
        div bl

        add ah, '0'
        mov bx, dx
        mov byte [bx+si], ah
        inc si

        mov ah, 00h
        cmp ax, 01h
        jl reversing
        jmp stiLoop

  reversing:
        mov cx, si
        xor si, si

     pushLoop:
        push word [bx+si]
        inc si
        inc si
        cmp si, cx
        jge popLoopStart
        jmp pushLoop

      popLoopStart:
          xor si, si

        popLoop:
          pop ax
          cmp ah, 24h
          jne insertHigh

        insertLow:
          mov byte [bx+si], al
          inc si

          cmp si, cx
          jge endits
          jmp popLoop


        insertHigh:
          mov byte [bx+si], ah
          inc si
          jmp insertLow

  endits:
        ret

        ;Function Algo
        ;1.  asval = value % 10
        ;2. char = asval + '0' 
        ;3.  value /= 10


;===================================:
;GETCH(). Wait for key press        :
;===================================:
getch:
        mov ax, 0700h
        int 21h
        ret
Title: Re: Converting decimal into String Problem
Post by: Gustav on November 20, 2005, 07:41:02 AM

using the stack to revert the digits could be coded more simple:


intToString:
        mov cx,sp
  stiLoop:
        mov bl, 10d
        div bl

        add ah, '0'
        push ax

        mov ah, 00h
        cmp ax, 01h
        jl reversing
        jmp stiLoop

reversing:
        mov bx,dx
popLoop:
        cmp cx,sp
        je popdone
          pop ax
          mov byte [bx], ah
          inc bx
          jmp popLoop
popdone:
        ret

Title: Re: Converting decimal into String Problem
Post by: PinoyProgramador on November 20, 2005, 11:05:22 PM
Thnks thats simple indeed.  :U
Title: Re: Converting decimal into String Problem
Post by: Gustav on November 21, 2005, 07:07:06 AM

You should be aware that your code will only work if ax is < 0A00h (decimal 2560), else you will get a divide error. Consider to use 16 bit registers for the division.
Title: Re: Converting decimal into String Problem
Post by: PinoyProgramador on November 21, 2005, 07:14:24 AM
Yeah i have that problem how do i solve that anyway? I see that al or ah the one that holds the Qoutient can only hold up to 256. How do i get by solve that. Or maybe there is a carry of the result where do i get it?
Title: Re: Converting decimal into String Problem
Post by: MichaelW on November 21, 2005, 08:08:44 AM
For a 16-bit source (divisor) the implied destination (dividend) will be the 32-bit value in DX:AX. If the initial value in DX is greater than 9, then the result (quotient) will overflow AX (e.g 0A0000 / 0Ah = 10000h). You can prevent this by clearing DX before the DIV instruction is executed.

Title: Re: Converting decimal into String Problem
Post by: Gustav on November 21, 2005, 10:06:29 AM

that's how the code should look like for 16bit (not tested!)


intToString:
        mov si, dx
        mov cx,sp
  stiLoop:
        xor dx,dx               
        mov bx, 10d
        div bx

        add dl, '0'
        push dx

        cmp ax, 01h
        jl reversing
        jmp stiLoop

reversing:
        mov dx,si
popLoop:
        cmp cx,sp
        je popdone
          pop ax
          mov byte [si], al
          inc si
          jmp popLoop
popdone:
        ret

Title: Re: Converting decimal into String Problem
Post by: PinoyProgramador on November 21, 2005, 11:09:05 AM
It worked !! That was simple.

What was happenning in my code why it isnt working? Wht has BX and not BL got to do with this code working? I see that thats the only part you seem to modify asid from the others you removed?
Title: Re: Converting decimal into String Problem
Post by: Gustav on November 21, 2005, 11:32:06 AM

using BL as divisor the division op is AX / BL = AL, remainder AH
using BX, it is DX:AX / BX = AX, remainder in DX

both the result and remainder must fit in AL/AX and AH/DX or an exception occurs
Title: Re: Converting decimal into String Problem
Post by: PinoyProgramador on November 22, 2005, 08:08:24 AM
Ok got it thnks :) :bg
Title: Re: Converting decimal into String Problem
Post by: PinoyProgramador on November 22, 2005, 08:25:31 AM
Wht is this code for? Where did sp come from?
cmp cx,sp
        je popdone



Title: Re: Converting decimal into String Problem
Post by: Gustav on November 22, 2005, 11:26:14 AM

sp ist the "stackpointer" register, which decrements on pushs ("push dx" decrements sp by 2) and increments on pops.
Title: Re: Converting decimal into String Problem
Post by: MichaelW on November 22, 2005, 02:58:20 PM
The instructions:

mov  cx, sp
...
cmp  cx, sp
je   popdone

Are an efficient method of ensuring that the number of pops matches the number of pushes (one that had never occurred to me, thanks Gustav). In 16-bit code each push will decrement SP by two, and each pop will increment SP by two. The attachment contains a trace of the code running in DEBUG. It shows what each execution of each instruction does to the registers.



[attachment deleted by admin]
Title: Re: Converting decimal into String Problem
Post by: HosAh on November 22, 2005, 06:21:47 PM
i also checked the code. it's nice&simple :U
Title: Re: Converting decimal into String Problem
Post by: Gustav on November 23, 2005, 05:22:32 AM
> i also checked the code. it's nice&simple

to win a price in a "nice and simple code" competition I would have suggested this variant:


intToString:
    mov si, dx
    mov cx, offset storedigit
    mov bx, 10
  stiLoop:
    xor dx, dx
    div bx
    add dl, '0'
    push dx
    push cx
    and ax, ax
    jnz stiLoop
    mov dx, si
    ret
  storedigit:   
    pop ax
    mov byte ptr[si], al
    inc si
    ret


however, for a noobie it's possibly "too simple" to understand what's going on here  :green

Title: Re: Converting decimal into String Problem
Post by: PinoyProgramador on November 26, 2005, 11:23:08 PM
Someone explain whats going on here?

intToString:
    mov si, dx                     ; strore value of SI to DX ?
    mov cx, offset storedigit ; set value of CX to address of storeDigit ?
    mov bx, 10                   ; set value of BX to 10
  stiLoop:
    xor dx, dx                    ; set DX to 0
    div bx                         ; divide here
    add dl, '0'
    push dx
    push cx
    and ax, ax                   ; what about here?       
    jnz stiLoop
    mov dx, si
    ret
  storedigit:                     ; What is this part for i dont see it executing ?
    pop ax
    mov byte ptr[si], al
    inc si
    ret
Title: Re: Converting decimal into String Problem
Post by: MichaelW on November 27, 2005, 12:26:20 AM
To understand how it works you must understand how the stack and the call and ret instructions work. For 16-bit code, a push instruction copies its operand to the address specified by ss:[sp] and then subtracts 2 from sp, and a pop instruction copies the value at the address specified by ss:[sp] to its operand and then adds 2 to sp, so sp always "points" to the most recently pushed value. A call instruction (a near call) effectively pushes the address of the next instruction (following the call instruction) onto the stack and jumps to the destination address. A ret instruction (a near return) effectively pops the most recently pushed value from the stack and uses it for the return destination. Assuming you were converting a two-digit number, the contents of the stack after the jnz stiLoop instuction would be:

return address back to code that called intToString
digit value
address of storedigit label
digit value
address of storedigit label

So the first ret instruction would "return" to the storedigit label. The pop ax instruction would then get the digit value off the stack, and the ret instruction would return to the storedigit label. The pop ax instruction would then get the next digit value off the stack, and since the return address back to code that called intToString would then be the most recently pushed value, the final ret instruction would return to the caller.

The and ax,ax followed by the jnz stiLoop are just another method of looping until ax is zero.
Title: Re: Converting decimal into String Problem
Post by: Gustav on November 27, 2005, 09:34:13 AM
>    mov si, dx                     ; strore value of SI to DX ?

that's because the 16 bit devision destroys DX, and since you are using DX for the string pointer which mustn't be changed its value is saved in SI and restored later.

Just use DEBUG to see what's happening. If someone told you that DEBUG shouldn't be used nowadays ignore it, it is just the right tool for your little program. Use the 'T' (=trace) command to single step through the code.



Title: Re: Converting decimal into String Problem
Post by: PinoyProgramador on November 27, 2005, 11:40:02 AM
So thats what the trace.zip was for. I didnt even bother to read everything in it coz they look like junks. Thnks for both replies :)

And thnks for the debug tut.  :U