News:

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

m32lib GetPercent need a correction

Started by ToutEnMasm, November 07, 2010, 06:54:01 AM

Previous topic - Next topic

ToutEnMasm

Quote
GetPercent proc source:DWORD, percent:DWORD

    LOCAL var1:DWORD

    mov var1, 100   ; to divide by 100

    fild source     ; load source integer
    fild var1       ; load 100
    fdiv            ; divide source by 100
    fild percent    ; load required percentage
    fmul            ; multiply 1% by required percentage
    fistp var1      ; store result in variable
    mov eax, var1          ;FPU STACK is +2 HERE and can't be used as this
    FINIT    ;---------- <<<<<<<<<<<< Added correction needed file getpcnt.asm
    ret

GetPercent endp

MichaelW

I can't find any problem. The FDIV and FMUL are actually encoded as FDIVP and FMULP (or at least they are if I assemble with ML 6.15).
eschew obfuscation

ToutEnMasm

This instructions aren't the problem,I agree.If you have read the comments the problem is:
Quote
THE STACK OF FPU IS +2 AT THE END OF THE FUNCTION ,NOT 0
The function couldn't be recall without ERROR.

MichaelW

The FPU stack is empty after the FISTP. I can call the procedure repeatedly without problems.
eschew obfuscation

jj2007

Michael is right, The problem exists only in your imagination. However, the GetPercent can certainly be optimised a little bit - 20 bytes instead of 36:
OPTION PROLOGUE:NONE
OPTION EPILOGUE:NONE

GetPercent proc source:DWORD, percent:DWORD
fild dword ptr [esp+4] ; load source integer
push 100
fidiv dword ptr [esp] ; divide source by 100
fimul dword ptr [esp+12] ; multiply 1% by required percentage
fistp dword ptr [esp] ; store result on stack
pop eax ; return in eax
ret 8
GetPercent endp

OPTION PROLOGUE:PrologueDef
OPTION EPILOGUE:EpilogueDef

ToutEnMasm

Perhaps you can made one effort: count on your fingers
Quote
  mov var1, 100   ; to divide by 100

    fild source     ; stack +1
    fild var1       ; lstack +1
    fdiv            ;
    fild percent    ; stack +1
    fmul            ;
    fistp var1      ;stack -1
    mov eax, var1         
    FINIT    ;---------- <<<<<<<<<<<< Added correction needed file getpcnt.asm
    ret
3-1 =2       not 0   

If you want more proof,try a loop with 4 or 5 recall of the function




 

jj2007

Quote from: ToutEnMasm on November 07, 2010, 01:44:11 PM
Perhaps you can made one effort: count on your fingers

Perhaps you can made one effort: Read Michael's comments ("The FDIV and FMUL are actually encoded as FDIVP and FMULP"), or launch Olly to see yourself.

And still, it could be optimised :bg

Intel(R) Celeron(R) M CPU        420  @ 1.60GHz (SSE3)
27      cycles for GetPercent
11      cycles for GetPercentJJ1
9       cycles for GetPercentJJ2

32      cycles for GetPercent
11      cycles for GetPercentJJ1
9       cycles for GetPercentJJ2

32      cycles for GetPercent
11      cycles for GetPercentJJ1
9       cycles for GetPercentJJ2

Code sizes:
36      for GetPercent
32      for GetPercentJJ1
32      for GetPercentJJ2

dedndave

he may be using a different assembler   :P

might try the explicit...

fmul st0,st1

ToutEnMasm

Quote
The FDIV and FMUL are actually encoded as FDIVP and FMULP"), or launch Olly to see yourself.
And what do you do if you have to work with an old compiler ?.

jj2007

Quote from: ToutEnMasm on November 07, 2010, 02:54:59 PM
Quote
The FDIV and FMUL are actually encoded as FDIVP and FMULP"), or launch Olly to see yourself.
And what do you do if you have to work with an old compiler ?.

ML 6.14, 6.15, 9.0 and JWasm all expose this behaviour. If you have a "compiler" older than 6.14, move it into the dustbin.

FORTRANS

Hi,

   CPU and FPU do not matter.  It is the assembler that
encodes the implied POP.  It is a matter of convention in
MASM from version 1.0 onwards.  Confuses some more
than others, and is only used with the one operand form.
IIRC.

Regards,

Steve N.

dedndave

i wasn't thinking he may be using an older masm
but, maybe tasm or fasm or some other creature
not sure how GoAsm handles it - knowing Jeremy, it is probably masm-compatible

jj2007

Just for fun, the non-FPU integer (JJ3) and SSE2 versions:
Intel(R) Celeron(R) M CPU        420  @ 1.60GHz (SSE3)
27      cycles for GetPercent
10      cycles for GetPercentJJ1
9       cycles for GetPercentJJ2
35      cycles for GetPercentJJ3
11      cycles for GetPercentJJ4
7       cycles for GetPercentSSE

Code sizes:
32      for GetPercentJJ1
32      for GetPercentJJ2
17      for GetPercentJJ3
33      for GetPercentJJ4
39      for GetPercentSSE

dedndave

prescott...
Intel(R) Pentium(R) 4 CPU 3.00GHz (SSE3)
38      cycles for GetPercent
24      cycles for GetPercentJJ1
20      cycles for GetPercentJJ2
46      cycles for GetPercentJJ3
21      cycles for GetPercentJJ4
18      cycles for GetPercentSSE

43      cycles for GetPercent
21      cycles for GetPercentJJ1
18      cycles for GetPercentJJ2
42      cycles for GetPercentJJ3
22      cycles for GetPercentJJ4
21      cycles for GetPercentSSE

clive

Atom
QuoteIntel(R) Atom(TM) CPU N270   @ 1.60GHz (SSE4)
117     cycles for GetPercent
51      cycles for GetPercentJJ1
46      cycles for GetPercentJJ2
100     cycles for GetPercentJJ3
50      cycles for GetPercentJJ4
40      cycles for GetPercentSSE

125     cycles for GetPercent
48      cycles for GetPercentJJ1
46      cycles for GetPercentJJ2
87      cycles for GetPercentJJ3
51      cycles for GetPercentJJ4
43      cycles for GetPercentSSE

Code sizes:
32      for GetPercentJJ1
32      for GetPercentJJ2
17      for GetPercentJJ3
33      for GetPercentJJ4
39      for GetPercentSSE
It could be a random act of randomness. Those happen a lot as well.