The MASM Forum Archive 2004 to 2012

General Forums => The Campus => Topic started by: korte on March 22, 2009, 12:02:37 PM

Title: floating sign test
Post by: korte on March 22, 2009, 12:02:37 PM


fsign macro
   fxam
   fstsw ax
   shr ax,1
   shaf
   endm


   fld   valuea
   fsign
   .if CARRY?
       ...
   .endif


its work!

but not nice

how to rewrite macro, using this format

  fld value
  .if FSIGN
     ....
  .endif


   
   
Title: Re: floating sign test
Post by: drizz on March 22, 2009, 01:41:25 PM
fsign macro
   fxam
   fstsw ax
   shr ax,1
   shaf
                           exitm<CARRY?>
   endm
Title: Re: floating sign test
Post by: korte on March 22, 2009, 01:46:08 PM


.if fsign

Error A2148: invalid symbol type in expression
Title: Re: floating sign test
Post by: drizz on March 22, 2009, 01:46:55 PM
.if fsign()

you must always use brackets when there is "exitm"
Title: Re: floating sign test
Post by: korte on March 22, 2009, 01:50:14 PM
work!

thx...
Title: Re: floating sign test
Post by: GregL on March 22, 2009, 05:33:12 PM
shaf ??

I assume you mean sahf.


Title: Re: floating sign test
Post by: GregL on March 22, 2009, 05:51:56 PM
It seems to work OK.  Never seen that one before.  Thanks.
Title: Re: floating sign test
Post by: jj2007 on March 22, 2009, 07:11:56 PM
Here is a variant accepting a real var argument.

include \masm32\include\masm32rt.inc

FSIGN MACRO rval:REQ
ffree st(7)
fld rval
fxam
fstsw ax
fincstp
shr ax, 1
sahf
exitm <Carry?>
ENDM

.code
r8pos REAL8 1.12345
r8minus REAL8 -1.12345
r8zeroA REAL8 0.0
r8zeroB REAL8 -0.0

start:
.if FSIGN(r8pos)
print "r8pos is negative", 13, 10
.else
print "r8pos is positive", 13, 10
.endif
.if FSIGN(r8minus)
print "r8minus is negative", 13, 10
.else
print "r8minus is positive", 13, 10
.endif
.if FSIGN(r8zeroA)
print "r8zeroA is negative", 13, 10
.else
print "r8zeroA is positive", 13, 10
.endif
.if FSIGN(r8zeroB)
print "r8zeroB is negative", 13, 10
.else
print "r8zeroB is positive", 13, 10
.endif

getkey
exit

end start
Title: Re: floating sign test
Post by: drizz on March 22, 2009, 07:30:47 PM
OR something useful  :P
fst real4 ptr [esp-4]
shl dword ptr [esp-4],1
.if carry?
Title: Re: floating sign test
Post by: korte on March 22, 2009, 08:10:16 PM
 :clap: :clap: :clap: :U
Title: Re: floating sign test
Post by: GregL on March 22, 2009, 08:35:18 PM
OK, carrying that on ...


r4sign MACRO R4:REQ
    mov eax, R4
    shl eax, 1
    EXITM <CARRY?>
ENDM

r8sign MACRO R8:REQ
    mov edx, OFFSET R8
    mov eax, DWORD PTR [edx+4]
    shl eax, 1
    EXITM <CARRY?>
ENDM

r10sign MACRO R10:REQ
    mov edx, OFFSET R10
    mov eax, DWORD PTR [edx+6]
    shl eax, 1
    EXITM <CARRY?>
ENDM

Title: Re: floating sign test
Post by: jj2007 on March 22, 2009, 09:04:34 PM
You guys have great ideas, but why not something useful and simple?

FSIGN MACRO rval:REQ
mov eax, OFFSET rval-4+sizeof rval
mov eax, [eax]
shl eax, 1
exitm <Carry?>
ENDM
Title: Re: floating sign test
Post by: GregL on March 22, 2009, 09:17:40 PM
Good idea jj.

You could also use bt eax, 31 instead of shl eax, 1.

Title: Re: floating sign test
Post by: jj2007 on March 22, 2009, 09:23:34 PM
Quote from: Greg on March 22, 2009, 09:17:40 PM
Good idea jj.

You could also use bt eax, 31 instead of shl eax, 1.


Hmmm.... 4 bytes instead of 2?
:bg

EDIT: I just realised I was horribly wasteful with the puter's resources.
This version does the job with 7 bytes:

FSIGN MACRO rval:REQ
mov eax, dword ptr [rval-4+sizeof rval] ; 5 bytes
shl eax, 1 ; 2 bytes
exitm <Carry?>
ENDM
Title: Re: floating sign test
Post by: raymond on March 23, 2009, 02:27:56 AM
Just to be picky based on another discussion regarding overwriting a register vs not overwriting it, how about the following (and we really want to know the SIGN, don't we??? thus making the source code a bit more legible)

Code:
FSIGN MACRO rval:REQ
   mov eax, dword ptr [rval-4+sizeof rval]   ; 5 bytes
   test eax, eax            ; 2 bytes
   exitm <Sign?>
ENDM
Title: Re: floating sign test
Post by: jj2007 on March 23, 2009, 05:06:22 AM
Quote from: raymond on March 23, 2009, 02:27:56 AM
Just to be picky based on another discussion regarding overwriting a register vs not overwriting it, how about the following (and we really want to know the SIGN, don't we??? thus making the source code a bit more legible)

Code:
FSIGN MACRO rval:REQ
   mov eax, dword ptr [rval-4+sizeof rval]   ; 5 bytes
   test eax, eax            ; 2 bytes
   exitm <Sign?>
ENDM

Raymond, I love it when you are getting picky :bg
But you may remember that in that historic debate about register-damaging programming practices the "mov" instruction was generally considered "destructive" and, worse, accused of changing register contents ::)
In a spirit of damage limitation, I therefore propose this variant:

Fsign MACRO rval:REQ ; usage: .if FSIGN(MyRealVar)
push eax
mov eax, dword ptr [rval-4+sizeof rval]
test eax, eax
pop eax
exitm <Sign?>
ENDM


While it certainly wastes valuable resources, it has the practical merit that noobs in general don't expect eax to be trashed after a harmless .if Sign?, pardon: .if Fsign()
:bg
Title: Re: floating sign test
Post by: Jimg on March 23, 2009, 02:14:16 PM
Building on everyone else's work,
Is there some reason you can't just use-

FSIGN MACRO rval:REQ
   test dword ptr [rval-4+sizeof rval],80000000h
   exitm <Sign?>
ENDM

?
or if you want smaller,
FSIGN MACRO rval:REQ
   test byte ptr [rval-1+sizeof rval],80h
   exitm <Sign?>
ENDM
Title: Re: floating sign test
Post by: jj2007 on March 23, 2009, 03:23:03 PM
Quote from: Jimg on March 23, 2009, 02:14:16 PM
Building on everyone else's work,
Is there some reason you can't just use-

...
or if you want smaller,
FSIGN MACRO rval:REQ
   test byte ptr [rval-1+sizeof rval],80h
   exitm <Sign?>
ENDM


Fantastic - 7 bytes, no registers trashed... :clap:
Title: Re: floating sign test
Post by: PBrennick on March 23, 2009, 04:16:54 PM
I love it!  :U

Paul
Title: Re: floating sign test
Post by: raymond on March 24, 2009, 03:37:45 AM
Just to prove that 10 heads are better than 9!!! :dance: :clap: :toothy

The way it developed, this thread should have been in the lab.
Title: Re: floating sign test
Post by: jj2007 on March 24, 2009, 06:13:48 AM
Quote from: raymond on March 24, 2009, 03:37:45 AM
Just to prove that 10 heads are better than 9!!! :dance: :clap: :toothy

You are right, but it's the exception from the rule "A committee is the only known animal with ten stomachs and no brain" :wink
Title: Re: floating sign test
Post by: jj2007 on March 24, 2009, 08:44:45 AM
Something was missing, here it is:

FSIGN MACRO rval
  ifb <rval>
    fst real8 ptr [esp-8]
    test byte ptr [esp-8+7], 80h ;; usage for sign of ST0: .if FSIGN()
  else
    test byte ptr [rval-1+sizeof rval], 80h ;; usage:  .if FSIGN(MyRealVar)
  endif
  EXITM <Sign?>
ENDM


Full test attached.

[attachment deleted by admin]
Title: Re: floating sign test
Post by: GregL on March 24, 2009, 05:23:45 PM
Quote from: JimgFSIGN MACRO rval:REQ
   test byte ptr [rval-1+sizeof rval],80h
   exitm <Sign?>
ENDM

Very nice.  :thumbu

Title: Re: floating sign test
Post by: jj2007 on March 24, 2009, 06:14:21 PM
Quote from: Greg on March 24, 2009, 05:23:45 PM

Very nice.  :thumbu


Thanx to the whole team ;-)

Try the slightly extended version above - marginally more complex, but you can use .FSIGN() to test the current FPU content. And it even works for dwords, qwords and tbytes :bg
Title: Re: floating sign test
Post by: raymond on March 25, 2009, 01:19:05 AM
QuoteSomething was missing, here it is:

That's a nice extension but there's no need to store the float on the stack as a REAL8. The sign bit will be the same, and always in the most significant bit, whether the float is stored as a REAL4, a REAL8 or a REAL10.

    fst dword ptr [esp-4]
    test byte ptr [esp-4+3], 80h
Title: Re: floating sign test
Post by: herge on March 25, 2009, 02:07:09 AM
 Hi jj2007:

The results from my computer are in!

---- Test local vars:

Loc4pos is positive
Loc4minus is negative
Loc4zeroA is positive
Loc4zeroB is negative

Loc8pos is positive
Loc8minus is negative
Loc8zeroA is positive
Loc8zeroB is negative

---- Test ST(0):

r10pos   is positive
r10minus is negative
r10zeroA is positive
r10zeroB is negative

---- Test global real variables:

r4pos   is positive
r4minus is negative
r4zeroA is positive
r4zeroB is negative

r8pos   is positive
r8minus is negative
r8zeroA is positive
r8zeroB is negative

r10pos   is positive
r10minus is negative
r10zeroA is positive
r10zeroB is negative


Regards herge

Title: Re: floating sign test
Post by: jj2007 on March 25, 2009, 05:42:40 AM
Quote from: raymond on March 25, 2009, 01:19:05 AM
The sign bit will be the same, and always in the most significant bit, whether the float is stored as a REAL4, a REAL8 or a REAL10.


Thanks for confirming that, Raymond, I was a bit uncertain about that hypothetical case where ST is a very small negative number, e.g. 1e-300, the rounding flags are set the wrong direction etc....
Title: Re: floating sign test
Post by: raymond on March 25, 2009, 08:20:25 PM
Quotehypothetical case where ST is a very small negative number, e.g. 1e-300, the rounding flags are set the wrong direction etc....

The rounding flag is immaterial. As for your concern, it should have been the same for converting from REAL10 to REAL8 for very small or large numbers.

If too small, the sign bit remains the same but would become +0 or -0.
If too large, the sign bit remains the same but would become +INFINITY or -INFINITY.