flat assembler
Message board for the users of flat assembler.

Index > Windows > Double Output problem

Author
Thread Post new topic Reply to topic
frankobach26



Joined: 10 Apr 2026
Posts: 11
Location: Kassel
frankobach26 23 Apr 2026, 15:43
Hello . I tried to make an example with Double number Input and Output but failed. Something IS Missing. Need Help. Thanks

Code:
format PE64 console
entry start

include 'win64a.inc'

section '.data' data readable writeable
    num1   dq ?
    num2   dq ?
    result dq ?

    fmt_in  db "%lf %lf",0
    msg     db "Zahlen eingeben:",13,10,0
    outmsg  db "Summe = ",0
    dot     db ".",0
    nl      db 13,10,0

    scale   dq 1000000.0

section '.bss' readable writeable
    buffer rb 64

section '.code' code readable executable

start:
    sub rsp, 28h

    ; INPUT
    lea rcx, [msg]
    call [printf]

    lea rcx, [fmt_in]
    lea rdx, [num1]
    lea r8,  [num2]
    call [scanf]

    ; CALCULATION (korrekt)
    movsd xmm0, [num1]
    addsd xmm0, [num2]

    ; =====================================================
    ; SPLIT CORRECTLY
    ; =====================================================

    cvttsd2si eax, xmm0        ; integer part
    mov ebx, eax

    cvtsi2sd xmm1, eax
    subsd xmm0, xmm1           ; fractional part (0.xxxx)
    mulsd xmm0, [scale]
    cvttsd2si ecx, xmm0        ; 6 decimals

    ; =====================================================
    ; OUTPUT
    ; =====================================================

    lea rcx, [outmsg]
    call [printf]

    mov eax, ebx
    call print_int

    lea rcx, [dot]
    call [printf]

    mov eax, ecx
    call print_frac_fixed

    lea rcx, [nl]
    call [printf]

    call [getchar]
    call [getchar]

    add rsp, 28h

    xor ecx, ecx
    call [ExitProcess]

; =========================================================
; INTEGER PRINT 
; =========================================================
print_int:
    sub rsp, 40h

    mov ebx, 10
    lea rsi, [buffer+32]
    mov byte [rsi], 0

.loop:
    xor edx, edx
    div ebx
    add dl, '0'
    dec rsi
    mov [rsi], dl
    test eax, eax
    jnz .loop

    mov rcx, rsi
    call [printf]

    add rsp, 40h
    ret

; =========================================================
; FRACTION PRINT 
; =========================================================
print_frac_fixed:
    sub rsp, 40h

    mov ebx, 100000   ; 6 digits fixed scale
    lea rsi, [buffer+32]
    mov byte [rsi], 0

.loopf:
    xor edx, edx
    div ebx
    add dl, '0'
    dec rsi
    mov [rsi], dl

    mov ebx, ebx
    shr ebx, 1
    cmp ebx, 0
    jne .loopf

    mov rcx, rsi
    call [printf]

    add rsp, 40h
    ret

section '.idata' import data readable
library kernel32,'kernel32.dll',\
        msvcrt,'msvcrt.dll'

import kernel32,\
       ExitProcess,'ExitProcess'

import msvcrt,\
       printf,'printf',\
       scanf,'scanf',\
       getchar,'getchar'    
Post 23 Apr 2026, 15:43
View user's profile Send private message Reply with quote
macomics



Joined: 26 Jan 2021
Posts: 1216
Location: Russia
macomics 23 Apr 2026, 17:47
1)
Code:
    mov eax, ecx
    call print_frac_fixed    
There is no value in ecx because you erased it by writing the parameter for previous calls to rcx. Try replacing it with, say, edi

2)
Code:
print_frac_fixed:
    sub rsp, 40h

    mov ebx, 100000   ; 6 digits fixed scale
    lea rsi, [buffer+32]
    mov byte [rsi], 0

.loopf:
    xor edx, edx
    div ebx
    add dl, '0'
    dec rsi
    mov [rsi], dl

    mov ebx, ebx
    shr ebx, 1
    cmp ebx, 0
    jne .loopf

    mov rcx, rsi
    call [printf]

    add rsp, 40h
    ret    
2.1) You're using a divisor for the highest digit, so why are you adding the digits to the buffer in reverse order?
2.2) After dividing by a large number, you should not take the remainder, but the quotient.
2.3) To move to the next digit, the divisor must be divided by the base of the number system. You're dividing by 2, not 10.
Code:
; =========================================================
; FRACTION PRINT
; =========================================================
print_frac_fixed:
    sub rsp, 40h

    mov ebx, 100000   ; 6 digits fixed scale
    lea rsi, [buffer]

.loopf:
    xor edx, edx
    div ebx
    add al, '0'
    mov [rsi], al
    inc rsi

;    mov ebx, ebx
    mov eax, ebx
    mov ebx, edx
    xor edx, edx
    mov ecx, 10
;    shr ebx, 1
    div ecx

    mov edx, eax  ; !!! OR xchg ebx, eax
    mov eax, ebx
    mov ebx, edx

    cmp ebx, 0
    jne .loopf

    mov byte [rsi], 0
    lea rcx, [buffer]
    call [printf]

    add rsp, 40h
    ret    
Post 23 Apr 2026, 17:47
View user's profile Send private message Reply with quote
AsmGuru62



Joined: 28 Jan 2004
Posts: 1798
Location: Toronto, Canada
AsmGuru62 23 Apr 2026, 20:06
As far as I know, scanf/printf functions (inside MSVCRT.DLL) already have all the converting capabilities: from text into double and back.
So, why use your own code to do all the conversions?
Post 23 Apr 2026, 20:06
View user's profile Send private message Send e-mail Reply with quote
frankobach26



Joined: 10 Apr 2026
Posts: 11
Location: Kassel
frankobach26 24 Apr 2026, 11:35
Thank you both for Help. I am quite new with fASM. I haven't managed to build a running correct result. Little Thing IS still wrong. Thanks.

Update: second example is running fine. All OK Here.

Code:
; nearly good , input 5.7 + 6.8 -> 12.§59104
; § sign is not welcome
;
format PE64 console
entry start

include 'win64a.inc'

section '.data' data readable writeable
    num1   dq ?
    num2   dq ?
    result dq ?

    fmt_in  db "%lf %lf",0
    msg     db "Zahlen eingeben:",13,10,0
    outmsg  db "Summe = ",0
    dot     db ".",0
    nl      db 13,10,0

    scale   dq 1000000.0

section '.bss' readable writeable
    buffer rb 64

section '.code' code readable executable

start:
    sub rsp, 28h

    ; INPUT
    lea rcx, [msg]
    call [printf]

    lea rcx, [fmt_in]
    lea rdx, [num1]
    lea r8,  [num2]
    call [scanf]

    ; CALCULATION (korrekt)
    movsd xmm0, [num1]
    addsd xmm0, [num2]

    ; =====================================================
    ; SPLIT CORRECTLY
    ; =====================================================

    cvttsd2si eax, xmm0        ; integer part
    mov ebx, eax

    cvtsi2sd xmm1, eax
    subsd xmm0, xmm1           ; fractional part (0.xxxx)
    mulsd xmm0, [scale]
    cvttsd2si ecx, xmm0        ; 6 decimals

    ; =====================================================
    ; OUTPUT
    ; =====================================================

    lea rcx, [outmsg]
    call [printf]

    mov eax, ebx
    call print_int

    lea rcx, [dot]
    call [printf]

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
    mov eax, ecx ; no ?
    ; mov eax, edi ; ???
    call print_frac_fixed
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

    lea rcx, [nl]
    call [printf]

    call [getchar]
    call [getchar]

    add rsp, 28h

    xor ecx, ecx
    call [ExitProcess]

; =========================================================
; INTEGER PRINT 
; =========================================================
print_int:
    sub rsp, 40h

    mov ebx, 10
    lea rsi, [buffer+32]
    mov byte [rsi], 0

.loop:
    xor edx, edx
    div ebx
    add dl, '0'
    dec rsi
    mov [rsi], dl
    test eax, eax
    jnz .loop

    mov rcx, rsi
    call [printf]

    add rsp, 40h
    ret

; =========================================================
; FRACTION PRINT
; =========================================================
print_frac_fixed:
    sub rsp, 40h

    mov ebx, 100000   ; 6 digits fixed scale
    lea rsi, [buffer]

.loopf:
    xor edx, edx
    div ebx
    add al, '0'
    mov [rsi], al
    inc rsi

;    mov ebx, ebx
    mov eax, ebx
    mov ebx, edx
    xor edx, edx
    mov ecx, 10
;    shr ebx, 1
    div ecx

    mov edx, eax  ; !!! OR xchg ebx, eax
    mov eax, ebx
    mov ebx, edx

    cmp ebx, 0
    jne .loopf

    mov byte [rsi], 0
    lea rcx, [buffer]
    call [printf]

    add rsp, 40h
    ret

section '.idata' import data readable
library kernel32,'kernel32.dll',\
        msvcrt,'msvcrt.dll'

import kernel32,\
       ExitProcess,'ExitProcess'

import msvcrt,\
       printf,'printf',\
       scanf,'scanf',\
       getchar,'getchar'    
    


New Update this example works:

Code:
; GO: 2.4 + 4.8 -> 7.200000, chill
format PE64 console
entry start

include 'win64a.inc'

section '.data' data readable writeable
    num1   dq ?
    num2   dq ?

    fmt_in  db "%lf %lf",0
    msg     db "Zahlen eingeben:",13,10,0
    outmsg  db "Summe = ",0
    dot     db ".",0
    nl      db 13,10,0

    scale   dq 1000000.0
    rounder dq 0.5

section '.bss' readable writeable
    buffer rb 64

section '.code' code readable executable

start:
    sub rsp, 28h

    ; INPUT
    lea rcx, [msg]
    call [printf]

    lea rcx, [fmt_in]
    lea rdx, [num1]
    lea r8,  [num2]
    call [scanf]

    ; ===============================
    ; CALCULATION (ROBUST)
    ; ===============================

    movsd xmm0, [num1]
    addsd xmm0, [num2]

    ; scale first!
    mulsd xmm0, [scale]
    addsd xmm0, [rounder]

    cvttsd2si rax, xmm0

    mov rbx, 1000000
    xor rdx, rdx
    div rbx              ; rax = int, rdx = frac

    mov r12, rax         ; save integer
    mov r13, rdx         ; save fraction

    ; ===============================
    ; OUTPUT
    ; ===============================

    lea rcx, [outmsg]
    call [printf]

    mov rax, r12
    call print_int64

    lea rcx, [dot]
    call [printf]

    mov rax, r13
    call print_frac6

    lea rcx, [nl]
    call [printf]

    call [getchar]
    call [getchar]

    add rsp, 28h

    xor ecx, ecx
    call [ExitProcess]

; ==================================
; PRINT INTEGER (64-bit safe)
; ==================================
print_int64:
    push rbx
    push rsi
    sub rsp, 40h

    mov rbx, 10
    lea rsi, [buffer+32]
    mov byte [rsi], 0

.loop:
    xor rdx, rdx
    div rbx
    add dl, '0'
    dec rsi
    mov [rsi], dl
    test rax, rax
    jnz .loop

    mov rcx, rsi
    call [printf]

    add rsp, 40h
    pop rsi
    pop rbx
    ret

; ==================================
; PRINT FRACTION (6 digits)
; ==================================
print_frac6:
    push rbx
    push rsi
    sub rsp, 40h

    mov rbx, 10
    lea rsi, [buffer+16]
    mov byte [rsi], 0

    mov rcx, 6

.loopf:
    xor rdx, rdx
    div rbx
    add dl, '0'
    dec rsi
    mov [rsi], dl
    dec rcx
    jnz .loopf

    mov rcx, rsi
    call [printf]

    add rsp, 40h
    pop rsi
    pop rbx
    ret

section '.idata' import data readable
library kernel32,'kernel32.dll',\
        msvcrt,'msvcrt.dll'

import kernel32,\
       ExitProcess,'ExitProcess'

import msvcrt,\
       printf,'printf',\
       scanf,'scanf',\
       getchar,'getchar'
    
Post 24 Apr 2026, 11:35
View user's profile Send private message Reply with quote
macomics



Joined: 26 Jan 2021
Posts: 1216
Location: Russia
macomics 24 Apr 2026, 12:55
Code:
; nearly good , input 5.7 + 6.8 -> 12.§59104
; § sign is not welcome
;
format PE64 console
entry start

include 'win64a.inc'

section '.data' data readable writeable
    num1   dq ?
    num2   dq ?
    result dq ?

    fmt_in  db "%lf %lf",0
    msg     db "Zahlen eingeben:",13,10,0
    outmsg  db "Summe = ",0
    dot     db ".",0
    nl      db 13,10,0

    scale   dq 1000000.0

section '.bss' readable writeable
    buffer rb 64

section '.code' code readable executable

start:
    sub rsp, 28h

    ; INPUT
    lea rcx, [msg]
    call [printf]

    lea rcx, [fmt_in]
    lea rdx, [num1]
    lea r8,  [num2]
    call [scanf]

    ; CALCULATION (korrekt)
    movsd xmm0, [num1]
    addsd xmm0, [num2]

    ; =====================================================
    ; SPLIT CORRECTLY
    ; =====================================================

    cvttsd2si eax, xmm0        ; integer part
    mov ebx, eax

    cvtsi2sd xmm1, eax
    subsd xmm0, xmm1           ; fractional part (0.xxxx)
    mulsd xmm0, [scale]

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
    ; cvttsd2si ecx, xmm0        ; 6 decimals
    cvttsd2si edi, xmm0        ; 6 decimals
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

    ; =====================================================
    ; OUTPUT
    ; =====================================================

    lea rcx, [outmsg]
    call [printf]

    mov eax, ebx
    call print_int

    lea rcx, [dot]
    call [printf]

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
    ; mov eax, ecx ; no ?
    mov eax, edi ; ???
    call print_frac_fixed
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

    lea rcx, [nl]
    call [printf]

    call [getchar]
    call [getchar]

    add rsp, 28h

    xor ecx, ecx
    call [ExitProcess]

; =========================================================
; INTEGER PRINT 
; =========================================================
print_int:
    sub rsp, 40h

    mov ebx, 10
    lea rsi, [buffer+32]
    mov byte [rsi], 0

.loop:
    xor edx, edx
    div ebx
    add dl, '0'
    dec rsi
    mov [rsi], dl
    test eax, eax
    jnz .loop

    mov rcx, rsi
    call [printf]

    add rsp, 40h
    ret

; =========================================================
; FRACTION PRINT
; =========================================================
print_frac_fixed:
    sub rsp, 40h

    mov ebx, 100000   ; 6 digits fixed scale
    lea rsi, [buffer]

.loopf:
    xor edx, edx
    div ebx
    add al, '0'
    mov [rsi], al
    inc rsi

;    mov ebx, ebx
    mov eax, ebx
    mov ebx, edx
    xor edx, edx
    mov ecx, 10
;    shr ebx, 1
    div ecx

    mov edx, eax  ; !!! OR xchg ebx, eax
    mov eax, ebx
    mov ebx, edx

    cmp ebx, 0
    jne .loopf

    mov byte [rsi], 0
    lea rcx, [buffer]
    call [printf]

    add rsp, 40h
    ret

section '.idata' import data readable
library kernel32,'kernel32.dll',\
        msvcrt,'msvcrt.dll'

import kernel32,\
       ExitProcess,'ExitProcess'

import msvcrt,\
       printf,'printf',\
       scanf,'scanf',\
       getchar,'getchar'
    
In your first code, you did not fully fix the error that I pointed out in 1). I fixed the error. Now your first code works too.
Post 24 Apr 2026, 12:55
View user's profile Send private message Reply with quote
AsmGuru62



Joined: 28 Jan 2004
Posts: 1798
Location: Toronto, Canada
AsmGuru62 24 Apr 2026, 15:56
Also, you can just use MSVCRT and good old FPU (more precision than fancy XMM):
Code:
format  PE64 CONSOLE 5.0
entry   start
stack   4000h, 4000h

    include 'Win64A.Inc'

; ---------------------------------------------------------------------------
section '.data' data readable writeable

    Value1      dq 0
    Value2      dq 0
    Summary     dq 0

    Prompt      db ' Enter two float point values:  ',0

    Added       db 0Dh,0Ah,'          Sum of these values:',0Dh,0Ah
                db '%s %16.8lf',0Dh,0Ah
                db '%s %16.8lf',0Dh,0Ah
                db '%s %16.8lf',0Dh,0Ah,0

    InFormat    db '%lf %lf',0
    SkipBlanks  db '                                ',0

; ---------------------------------------------------------------------------
section '.code' code readable executable

; ---------------------------------------------------------------------------
; PROGRAM ENTRY POINT
; ---------------------------------------------------------------------------
align 16
start:
    push    rax             ; align stack on 16

    invoke  printf, Prompt
    invoke  scanf, InFormat, Value1, Value2

    fld     [Value1]
    fadd    [Value2]
    fstp    [Summary]

    mov     r10, SkipBlanks
    invoke  printf, Added, r10, [Value1], r10, [Value2], r10, [Summary]

    invoke  ExitProcess, 0

; ---------------------------------------------------------------------------
section '.idata' import data readable writeable

    library kernel32,'KERNEL32.DLL',msvcrt,'MSVCRT.DLL'

    include 'API\Kernel32.Inc'

    import msvcrt,scanf,'scanf',printf,'printf'
    

Output:
Code:
 Enter two float point values:  8274.98398 1e2

          Sum of these values:
                                    8274.98398000
                                     100.00000000
                                    8374.98398000
    
Post 24 Apr 2026, 15:56
View user's profile Send private message Send e-mail Reply with quote
Display posts from previous:
Post new topic Reply to topic

Jump to:  


< Last Thread | Next Thread >
Forum Rules:
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You can download files in this forum


Copyright © 1999-2026, Tomasz Grysztar. Also on GitHub, YouTube.

Website powered by rwasa.