News:

MASM32 SDK Description, downloads and other helpful links
MASM32.com New Forum Link
masmforum WebSite

What's wrong in this code?

Started by frktons, November 18, 2010, 02:06:01 PM

Previous topic - Next topic

frktons

Trying to implement a chunk of code Clive posted some months ago, I have strange results:

Quote
0
20
0
19
0
18
0
17
0
16
0
15
0
14
0
13
0
12
0
11
010
09
08
07099060990509904099030990209901099900,000

something is wrong with this code:


; ---------------------------------------------------------------------------
;  Algo #02  to test and code to manage the display of the results.
; ---------------------------------------------------------------------------
include \masm32\include\masm32rt.inc

.686
.mmx
.xmm

;----------------------------------------------------------------------------
; Equates used
;----------------------------------------------------------------------------

Four  EQU  4
One   EQU  1

.data


align Four

;---------------------------------------------------------------------------------
   
    NumToTest        dword 0
                     dword 9
                     dword 10
                     dword 99
                     dword 100
                     dword 999
                     dword 1000
                     dword 9999
                     dword 10000
                     dword 99999
                     dword 100000
                     dword 999999
                     dword 1000000
                     dword 9999999
                     dword 10000000
                     dword 99999999
                     dword 100000000
                     dword 999999999
                     dword 1000000000
                     dword 4294967295

    PtrNumToTest     dword NumToTest

    NumFormat        db  20 dup (0)

    PtrNumFormat     dword NumFormat

; ---------------------------------------------------------------------------

.code

start:

Main proc

align Four

    CALL AlgoN2
    inkey " ---- OK ------ ",13,10
    exit

Main endp


AlgoN2 proc


; EAX = 32-bit number
; ESI = string buffer for NUL terminated ASCII
; Uses ESI,EDI,EAX,ECX,EDX,EBX

    xor  ebx, ebx
    mov  ebx, 20
    lea  esi, NumFormat
    lea  eax, NumToTest
    mov  PtrNumToTest, eax

ConvertNext:

    mov  eax, PtrNumToTest
    mov  eax, [eax]
   
    push 0           ; Mark stack end with NUL

divloop:

    mov  ecx,1000       ; Divide into 3 digit groups
    xor  edx,edx ; Clear high order 32-bit for divide
    idiv ecx ; eax = edx:eax / ecx, edx = edx:eax % ecx

    mov  edi,eax ; Save division result

    mov  ecx,10      ; Subdivide in 10's
    mov  eax,edx ; Get remainder

    or   edi,edi      ; Still number left, so at least 3 digits in remainder
    jnz  digit000

    cmp  eax,10 ; remainder has one digit
    jb   digit0

    cmp  eax,100 ; remainder has two digits
    jb   digit00

digit000:               ; 3 digits

    xor  edx,edx      ; Clear high order 32-bit for divide
    idiv ecx            ; eax = edx:eax / ecx, edx = edx:eax % ecx
    add  edx,30h      ; += '0'
    push edx      ; Stack

digit00:               ; 2 digits

    xor  edx,edx        ; Clear high order 32-bit for divide
    idiv ecx            ; eax = edx:eax / ecx, edx = edx:eax % ecx
    add  edx,30h        ; += '0'
    push edx            ; Stack

digit0:           ; 1 digit

    xor  edx,edx        ; Clear high order 32-bit for divide
;   idiv ecx            ; eax = edx:eax / ecx, edx = edx:eax % ecx
                        ; The digit here is 0 to 9 no need to divide
    add  edx,30h        ; += '0'
    push edx            ; Stack

    mov  eax,edi ; Recover remaining number

    or   eax,eax ; Zero?
    jz   poploop

    push 2Ch ; Comma added to groups of three digits
    jmp  divloop

poploop:

    pop  eax ; Recover next digit
    mov  [esi],al      ; Add to string
    inc  esi
    or   eax,eax ; Was it a NUL?
    jnz  poploop
   
    push ebx
    push esi
   
; -----------------------------------------------------------------
    print ADDR NumFormat,13,10
    print sstr$(ebx),13,10
; -----------------------------------------------------------------

    pop  esi
    pop  ebx

    add  PtrNumToTest, Four ; Next number to convert
    sub  ebx, One
    jnz  ConvertNext
 

    ret

AlgoN2 endp

;----------------------------------------------------------------------------
; End of program
;----------------------------------------------------------------------------

end start

::) ::) ::)
Mind is like a parachute. You know what to do in order to use it :-)

clive

; ---------------------------------------------------------------------------
;  Algo #02  to test and code to manage the display of the results.
; ---------------------------------------------------------------------------
include \masm32\include\masm32rt.inc

.686
.mmx
.xmm

;----------------------------------------------------------------------------
; Equates used
;----------------------------------------------------------------------------

Four  EQU  4
One   EQU  1

.data


align Four

;---------------------------------------------------------------------------------

    NumToTest        dword 0
                     dword 9
                     dword 10
                     dword 99
                     dword 100
                     dword 999
                     dword 1000
                     dword 9999
                     dword 10000
                     dword 99999
                     dword 100000
                     dword 999999
                     dword 1000000
                     dword 9999999
                     dword 10000000
                     dword 99999999
                     dword 100000000
                     dword 999999999
                     dword 1000000000
                     dword 4294967295

    PtrNumToTest     dword offset NumToTest

    NumFormat        db  20 dup (0)

    PtrNumFormat     dword offset NumFormat

; ---------------------------------------------------------------------------

.code

start:

Main proc

align Four

    CALL AlgoN2

    inkey " ---- OK ------ ",13,10
    exit

Main endp


AlgoN2 proc


; EAX = 32-bit number
; ESI = string buffer for NUL terminated ASCII
; Uses ESI,EDI,EAX,ECX,EDX,EBX

    xor  ebx, ebx
    mov  ebx, 20
    lea  eax, NumToTest
    mov  PtrNumToTest, eax

ConvertNext:

    lea  esi, NumFormat ; Helps to initialize it every time round

    mov  eax, PtrNumToTest
    mov  eax, [eax]

    push 0           ; Mark stack end with NUL

divloop:

    mov  ecx,1000       ; Divide into 3 digit groups
    xor  edx,edx ; Clear high order 32-bit for divide
    idiv ecx ; eax = edx:eax / ecx, edx = edx:eax % ecx

    mov  edi,eax ; Save division result

    mov  ecx,10      ; Subdivide in 10's
    mov  eax,edx ; Get remainder

    or   edi,edi      ; Still number left, so at least 3 digits in remainder
    jnz  digit000

    cmp  eax,10 ; remainder has one digit
    jb   digit0

    cmp  eax,100 ; remainder has two digits
    jb   digit00

digit000:               ; 3 digits

    xor  edx,edx      ; Clear high order 32-bit for divide
    idiv ecx            ; eax = edx:eax / ecx, edx = edx:eax % ecx
    add  edx,30h      ; += '0'
    push edx      ; Stack

digit00:               ; 2 digits

    xor  edx,edx        ; Clear high order 32-bit for divide
    idiv ecx            ; eax = edx:eax / ecx, edx = edx:eax % ecx
    add  edx,30h        ; += '0'
    push edx            ; Stack

digit0:           ; 1 digit

if 0
    xor  edx,edx        ; Clear high order 32-bit for divide
    idiv ecx            ; eax = edx:eax / ecx, edx = edx:eax % ecx
    add  edx,30h        ; += '0'
    push edx            ; Stack
else
                        ; The digit here (IN EAX) is 0 to 9 no need to divide
    add  eax,30h        ; += '0'
    push eax            ; Stack
endif

    mov  eax,edi ; Recover remaining number

    or   eax,eax ; Zero?
    jz   poploop

    push 2Ch ; Comma added to groups of three digits
    jmp  divloop

poploop:

    pop  eax ; Recover next digit
    mov  [esi],al      ; Add to string
    inc  esi
    or   eax,eax ; Was it a NUL?
    jnz  poploop

    push ebx
    push esi

; -----------------------------------------------------------------
    print ADDR NumFormat,13,10
    print sstr$(ebx),13,10,10
; -----------------------------------------------------------------

    pop  esi
    pop  ebx

    add  PtrNumToTest, Four ; Next number to convert
    sub  ebx, One
    jnz  ConvertNext


    ret

AlgoN2 endp

;----------------------------------------------------------------------------
; End of program
;----------------------------------------------------------------------------

end start


0
20

9
19

10
18

99
17

100
16

999
15

1,000
14

9,999
13

10,000
12

99,999
11

100,000
10

999,999
9

1,000,000
8

9,999,999
7

10,000,000
6

99,999,999
5

100,000,000
4

999,999,999
3

1,000,000,000
2

4,294,967,295
1

---- OK ------
It could be a random act of randomness. Those happen a lot as well.

frktons

Thanks Clive  :U

Now I can insert it into the Testbed and see how it performs.  :bg
Mind is like a parachute. You know what to do in order to use it :-)

brethren


frktons

Quote from: brethren on November 18, 2010, 06:58:01 PM
Four  EQU  4
One   EQU  1


:red

I like code like this one:



sub  ebx,  One

add  eax,  Four

  :P

Frank
Mind is like a parachute. You know what to do in order to use it :-)