flat assembler
Message board for the users of flat assembler.

Index > Windows > Procedure conversion C++ to Fasm

Author
Thread Post new topic Reply to topic
Picnic



Joined: 05 May 2007
Posts: 1288
Location: Paradise Falls
Picnic
Hi all,

I need to convert a C++ function in fasm. Below is my effort seeing the vc++ disassembly, i'm not using often fpu instructions so suggestions welcome.

C++ code
Code:
inline bool LockFrameRate(unsigned int &frame_rate, LARGE_INTEGER &ticksPerSecond)
{
    static double lastTime = 0;
    double elapsedTime = 0;
    LARGE_INTEGER Timer;

    QueryPerformanceCounter(&Timer);

    double currentTime = ((Timer.QuadPart * 1000) / ticksPerSecond.QuadPart) * 0.001;

    elapsedTime = currentTime - lastTime;

    if( elapsedTime > (1.0 / frame_rate) )
    {

        lastTime = currentTime;


        return true;
    }

    return false;
}
    


Fasm code
Code:
proc LockFrameRate frame_rate:dword, pticksPerSecond:dword

            locals
                Timer dq ?
                currentTime dq ?
                elapsedTime dq ?
                Var1 dq 1000.0
                Var2 dq 0.001
                Var3 dq 1.0
                Var4 dq ?
            endl

            invoke QueryPerformanceCounter, addr Timer

            fild qword [Timer]
            fmul qword [Var1]
            mov eax, [pticksPerSecond]
            fild qword [eax]
            fdivp st1, st0
            fmul qword [Var2]
            fstp qword [currentTime]
            fld qword [currentTime]
            fsub qword [lastTime]
            fstp qword [elapsedTime]
            lea ecx, [Var4]
            mov eax, [frame_rate]
            mov dword [ecx], eax
            mov dword [ecx+4], 0
            fild qword [Var4]
            fdivr qword [Var3]
            fcomp qword [elapsedTime]
            fnstsw ax
            test ah, 5
            jp .ret
            fld qword [currentTime]
            fstp qword [lastTime]
            mov eax, 1
            ret
.ret:
            xor eax, eax
            ret
endp
    
Post 16 Jan 2011, 18:33
View user's profile Send private message Reply with quote
idle



Joined: 06 Jan 2011
Posts: 360
Location: Ukraine
idle
hi Picnic
could you describe verbally what exactly you are going to do

((Timer.QuadPart * 1000) / ticksPerSecond.QuadPart) * 0.001 = Timer / ticksPerSecond

the fp-code seems wrong
Post 16 Jan 2011, 22:04
View user's profile Send private message Reply with quote
Picnic



Joined: 05 May 2007
Posts: 1288
Location: Paradise Falls
Picnic
Hi idle,

I see the relationship here, could use some hints about the possible reason. When simplifying the division program is not working. Smile

Where you locate the error?

p.s
pticksPerSecond is a pointer to ticksPerSecond qword
lastTimeA is a qword, strats with value 0
Post 16 Jan 2011, 23:15
View user's profile Send private message Reply with quote
idle



Joined: 06 Jan 2011
Posts: 360
Location: Ukraine
idle
- 1000 * 0.001 = 1, so remove those
- fmul [var1] // fmul [var2] = 1, so remove those
- fstp [currentTime] // fld [currentTime] = fld st0 // fstp [currentTime]
- fild [Var4] = fild qword[ecx]
- fcomp [elapsedTime], could be kept in fpu so
- jp .ret, use and ah,01000101b // jnz .ret

use frame_rate directly
there is a fld1 instruction to load 1.0 into st0
i'm sleepy, sorry if wrong
Post 17 Jan 2011, 01:04
View user's profile Send private message Reply with quote
Picnic



Joined: 05 May 2007
Posts: 1288
Location: Paradise Falls
Picnic
Thanks for the useful tips idle. i'm sleepy too, enough for today.

Code:
proc LockFrameRate frame_rate:dword, pticksPerSecond:dword

            locals
                Timer dq ?
                currentTime dq ?
                elapsedTime dq ? 
            endl

            invoke QueryPerformanceCounter, addr Timer
            call TestApi

            fild qword [Timer]
            mov eax, [pticksPerSecond]
            fild qword [eax]
            fdivp st1, st0
            fld st0
            fstp qword [currentTime]
            fsub qword [lastTimeA]
            fstp qword [elapsedTime]    
            fld1         
            fidiv dword [frame_rate]
            fcomp qword [elapsedTime]
            fnstsw ax
            test ah, 5
            jp .ret
            fld qword [currentTime]
            fstp qword [lastTimeA]
            mov eax, 1
            ret
.ret:    
            xor eax, eax
            ret
endp
    
Post 17 Jan 2011, 23:34
View user's profile Send private message Reply with quote
idle



Joined: 06 Jan 2011
Posts: 360
Location: Ukraine
idle
Picnic, avoid memory usage whenever possible.
Sets CF=1 if lastTimeA updated, destroys flags and eax.
:)=
Code:
proc LockFrameRate; frame_rate:dword, pticksPerSecond:dword
        sub     esp,8
        invoke  QueryPerformanceCounter,esp
        fild    qword[esp]       ;Timer
        add     esp,8
        mov     eax,[esp+8]
        fild    qword[eax]       ;ticksPerSecond
        fdivp   st1,st0          ;currentTime
        fld     st0
        fsub    qword[lastTimeA] ;elapsedTime
        fld1
        fidiv   dword[esp+4]     ;1/frame_rate
        fcompp
        fstsw   ax
        shr     ah,1
        jc      @f
        fstp    st0
        ret     8
     @@:fstp    qword[lastTimeA]
        ret     8
endp
    
Post 18 Jan 2011, 08:02
View user's profile Send private message Reply with quote
Picnic



Joined: 05 May 2007
Posts: 1288
Location: Paradise Falls
Picnic
That's more elegant, and likely more efficient, too. Smile
Post 19 Jan 2011, 09:00
View user's profile Send private message 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-2020, Tomasz Grysztar. Also on GitHub, YouTube, Twitter.

Website powered by rwasa.