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
fsign macro
fxam
fstsw ax
shr ax,1
shaf
exitm<CARRY?>
endm
.if fsign
Error A2148: invalid symbol type in expression
.if fsign()
you must always use brackets when there is "exitm"
work!
thx...
shaf ??
I assume you mean sahf.
It seems to work OK. Never seen that one before. Thanks.
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
OR something useful :P
fst real4 ptr [esp-4]
shl dword ptr [esp-4],1
.if carry?
:clap: :clap: :clap: :U
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
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
Good idea jj.
You could also use bt eax, 31 instead of shl eax, 1.
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
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
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
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
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:
I love it! :U
Paul
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.
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
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]
Quote from: JimgFSIGN MACRO rval:REQ
test byte ptr [rval-1+sizeof rval],80h
exitm <Sign?>
ENDM
Very nice. :thumbu
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
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
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
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....
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.