Hi All,
my little snippet to check if unsigned value is in bounds
(inclusive), 8 instructions 3 registers. i have another version too,
8 instrs. *2 register* but it is not much compiler friendly.
Also, conditions:
1) EAX original value on ret
2) ZFlag or CFlag re/set on error
2) must return 0 not0 as info in a register,
respectively for low/hi bound overflow
or viceversa
ideas,improvements ?
..is_inbound:
mov eax,value
mov ecx,MAX_BOUND
cmp eax,MIN_BOUND
sbb edx,edx
cmp ecx,eax
not edx
sbb ecx,ecx
xor ecx,edx
jz .err
Cheers
--
.:hopcode[marc:rainer:kranz]:.
x64 Assembly Lab
http://sites.google.com/site/x64lab
|
|
0
|
|
|
|
Reply
|
hopcode
|
3/24/2011 10:22:54 PM |
|
On Mar 24, 5:22=A0pm, hopcode <hopc...@nospicedham.nullnichtsnada.com>
wrote:
> Hi All,
> my little snippet to check if unsigned value is in bounds
> (inclusive), 8 instructions 3 registers. i have another version too,
> 8 instrs. *2 register* but it is not much compiler friendly.
> Also, conditions:
>
> 1) EAX original value on ret
> 2) ZFlag or CFlag re/set on error
> 2) must return 0 not0 as info in a register,
> =A0 =A0 respectively for low/hi bound overflow
> =A0 =A0 or viceversa
>
> ideas,improvements ?
>
> .is_inbound:
> =A0 mov eax,value
> =A0 mov ecx,MAX_BOUND
> =A0 cmp eax,MIN_BOUND
> =A0 sbb edx,edx
> =A0 cmp ecx,eax
> =A0 not edx
> =A0 sbb ecx,ecx
> =A0 xor ecx,edx
> =A0 jz .err
How about:
mov ebx,eax
sub ebx,MIN_BOUND
cmp ebx,(MAX_BOUND-MIN_BOUND+1)
setae bl
movzx ebx,bl
Shorter, although not necessarily faster (setcc is slow on some
processors). Carry set if out of range, ebx set to 0/1 (in/out of
range). And if you only need the carry returned, you can eliminate
the last two instructions.
|
|
0
|
|
|
|
Reply
|
robertwessel2
|
3/24/2011 11:39:49 PM
|
|
Il 25.03.2011 00:39, robertwessel2@yahoo.com ha scritto:
> On Mar 24, 5:22 pm, hopcode<hopc...@nospicedham.nullnichtsnada.com>
> wrote:
>> Hi All,
>> my little snippet to check if unsigned value is in bounds
>> (inclusive), 8 instructions 3 registers. i have another version too,
>> 8 instrs. *2 register* but it is not much compiler friendly.
>> Also, conditions:
>>
>> 1) EAX original value on ret
>> 2) ZFlag or CFlag re/set on error
>> 2) must return 0 not0 as info in a register,
>> respectively for low/hi bound overflow
>> or viceversa
>>
>> ideas,improvements ?
>>
>> .is_inbound:
>> mov eax,value
>> mov ecx,MAX_BOUND
>> cmp eax,MIN_BOUND
>> sbb edx,edx
>> cmp ecx,eax
>> not edx
>> sbb ecx,ecx
>> xor ecx,edx
>> jz .err
>
>
> How about:
>
> mov ebx,eax
> sub ebx,MIN_BOUND
> cmp ebx,(MAX_BOUND-MIN_BOUND+1)
> setae bl
> movzx ebx,bl
>
> Shorter, although not necessarily faster (setcc is slow on some
> processors). Carry set if out of range, ebx set to 0/1 (in/out of
> range). And if you only need the carry returned, you can eliminate
> the last two instructions.
Hi robertwessel,
setae bl is necessary.it drives all the music.
I am testing a new version just in this minutes...
Cheers,
--
.:hopcode[marc:rainer:kranz]:.
x64 Assembly Lab
http://sites.google.com/site/x64lab
|
|
0
|
|
|
|
Reply
|
hopcode
|
3/25/2011 1:11:02 AM
|
|
Il 24.03.2011 23:22, hopcode ha scritto:
> Hi All,
> my little snippet to check if unsigned value is in bounds
> (inclusive), 8 instructions 3 registers. i have another version too,
> 8 instrs. *2 register* but it is not much compiler friendly.
> Also, conditions:
>
> 1) EAX original value on ret
> 2) ZFlag or CFlag re/set on error
> 2) must return 0 not0 as info in a register,
> respectively for low/hi bound overflow
> or viceversa
>
> ideas,improvements ?
>
> ..is_inbound:
> mov eax,value
> mov ecx,MAX_BOUND
> cmp eax,MIN_BOUND
> sbb edx,edx
> cmp ecx,eax
> not edx
> sbb ecx,ecx
> xor ecx,edx
> jz .err
>
Coming from the bottomless dark space...of my brain
a new version, 5 instructions 2 register
ZF=0 ok
ZF=1 not in range
if ZF=1 not in range
CF=1 low bound error
CF=0 hi bound error
..is_inbound:
mov eax,value
cmp eax,MIN_BOUND
sbb ecx,ecx
cmp eax,MAX_BOUND+1
adc ecx,0
ret 0
Cheers
--
.:hopcode[marc:rainer:kranz]:.
x64 Assembly Lab
http://sites.google.com/site/x64lab
|
|
0
|
|
|
|
Reply
|
hopcode
|
3/25/2011 1:26:47 AM
|
|
"robertwessel2@yahoo.com" <robertwessel2@nospicedham.yahoo.com> writes:
> On Mar 24, 5:22=A0pm, hopcode <hopc...@nospicedham.nullnichtsnada.com>
> wrote:
>> Hi All,
>> my little snippet to check if unsigned value is in bounds
>> (inclusive), 8 instructions 3 registers. i have another version too,
>> 8 instrs. *2 register* but it is not much compiler friendly.
>> Also, conditions:
>>
>> 1) EAX original value on ret
>> 2) ZFlag or CFlag re/set on error
>> 2) must return 0 not0 as info in a register,
>> =A0 =A0 respectively for low/hi bound overflow
>> =A0 =A0 or viceversa
Do you really need the third point?
If so, are your values signed or unsigned (i.e., is -7/0xfffffff8 a bound
underflow for the range [3..5], or an overflow)?
It's so much easier without that requirement :)
>>
>> ideas,improvements ?
>>
>> .is_inbound:
>> =A0 mov eax,value
>> =A0 mov ecx,MAX_BOUND
>> =A0 cmp eax,MIN_BOUND
>> =A0 sbb edx,edx
>> =A0 cmp ecx,eax
>> =A0 not edx
>> =A0 sbb ecx,ecx
>> =A0 xor ecx,edx
>> =A0 jz .err
>
>
> How about:
>
> mov ebx,eax
> sub ebx,MIN_BOUND
> cmp ebx,(MAX_BOUND-MIN_BOUND+1)
> setae bl
> movzx ebx,bl
Or equivalently:
lea ebx,[eax - MIN_BOUND]
cmp ebx,(MAX_BOUND - MIN_BOUND)
sbb ebx, ebx
However, now that I reread the specification, that's not what's asked for
in the returned register. It should say whether the value is below or abo=
ve
the range (if outside).
For that (assuming unsigned values), how about:
cmp eax, MIN_BOUND
sbb ebx, ebx // ebx =3D 0 if MIN_BOUND <=3D eax, -1 if eax < =
MIN_BOUND
cmp eax, MAX_BOUND + 1
adc ebx, ebx // ebx =3D 0 if MAX_BOUND < eax
// -1 if MIN_BOUND <=3D eax <=3D MAX_BOUND
// -2 if eax < MIN_BOUND
cmp ebx, -1 // Z flag set if inside range.
// ebx =3D=3D 0 (and C flag set) if above range
// ebx =3D=3D -2 (and C flag clear) if below ran=
ge.
Now, the latency of sbb and adc aren't exactly stellar (2 cycles each on =
a
Core 2) and they won't parallelize. Using setae instead of sbb might=20
be faster, i.e.,
cmp eax, MIN_BOUND
setae ebx // bl =3D 1 if MIN_BOUND <=3D eax, 0 if eax < MI=
N_BOUND
cmp eax, MAX_BOUND + 1
adc bl, bl // bl =3D 0 if MAX_BOUND < eax
// 2 if MIN_BOUND <=3D eax <=3D MAX_BOUND
// 1 if eax < MIN_BOUND
cmp bl, 2 // Z flag set if inside range.
// ebx =3D=3D 0 if above range
// ebx =3D=3D 1 if below range.
Best of luck
/L =20
--=20
Lasse Reichstein Holst Nielsen
DHTML Death Colors: <URL:http://www.infimum.dk/HTML/rasterTriangleDOM.ht=
ml>
'Faith without judgement merely degrades the spirit divine.'
|
|
0
|
|
|
|
Reply
|
Lasse
|
3/25/2011 5:42:36 PM
|
|
Il 25.03.2011 18:42, Lasse Reichstein Nielsen ha scritto:
> "robertwessel2@yahoo.com"<robertwessel2@nospicedham.yahoo.com> writes:
>
>> On Mar 24, 5:22 pm, hopcode<hopc...@nospicedham.nullnichtsnada.com>
>> wrote:
>>> Hi All,
>>> my little snippet to check if unsigned value is in bounds
>>> (inclusive), 8 instructions 3 registers. i have another version too,
>>> 8 instrs. *2 register* but it is not much compiler friendly.
>>> Also, conditions:
>>>
>>> 1) EAX original value on ret
>>> 2) ZFlag or CFlag re/set on error
>>> 2) must return 0 not0 as info in a register,
>>> respectively for low/hi bound overflow
>>> or viceversa
>
> Do you really need the third point?
> If so, are your values signed or unsigned (i.e., is -7/0xfffffff8 a bound
> underflow for the range [3..5], or an overflow)?
>
> It's so much easier without that requirement :)
>
>>>
>>> ideas,improvements ?
>>>
>>> .is_inbound:
>>> mov eax,value
>>> mov ecx,MAX_BOUND
>>> cmp eax,MIN_BOUND
>>> sbb edx,edx
>>> cmp ecx,eax
>>> not edx
>>> sbb ecx,ecx
>>> xor ecx,edx
>>> jz .err
>>
>>
>> How about:
>>
>> mov ebx,eax
>> sub ebx,MIN_BOUND
>> cmp ebx,(MAX_BOUND-MIN_BOUND+1)
>> setae bl
>> movzx ebx,bl
>
> Or equivalently:
> lea ebx,[eax - MIN_BOUND]
> cmp ebx,(MAX_BOUND - MIN_BOUND)
> sbb ebx, ebx
>
Hi Lasse,
very nice. it's a pity it doesnt return the hi/low
trenspassed bound on error.
> However, now that I reread the specification, that's not what's asked for
> in the returned register. It should say whether the value is below or above
> the range (if outside).
>
>
> For that (assuming unsigned values), how about:
> cmp eax, MIN_BOUND
> sbb ebx, ebx // ebx = 0 if MIN_BOUND<= eax, -1 if eax< MIN_BOUND
> cmp eax, MAX_BOUND + 1
> adc ebx, ebx // ebx = 0 if MAX_BOUND< eax
> // -1 if MIN_BOUND<= eax<= MAX_BOUND
> // -2 if eax< MIN_BOUND
> cmp ebx, -1 // Z flag set if inside range.
> // ebx == 0 (and C flag set) if above range
> // ebx == -2 (and C flag clear) if below range.
>
> Now, the latency of sbb and adc aren't exactly stellar (2 cycles each on a
> Core 2) and they won't parallelize. Using setae instead of sbb might
> be faster, i.e.,
Yes, according latency table SETCC is on my 45nm Core faster
than sbb/adc.
>
> cmp eax, MIN_BOUND
> setae ebx // bl = 1 if MIN_BOUND<= eax, 0 if eax< MIN_BOUND
> cmp eax, MAX_BOUND + 1
> adc bl, bl // bl = 0 if MAX_BOUND< eax
> // 2 if MIN_BOUND<= eax<= MAX_BOUND
> // 1 if eax< MIN_BOUND
> cmp bl, 2 // Z flag set if inside range.
> // ebx == 0 if above range
> // ebx == 1 if below range.
>
Yesterday i posted something similiar (see post below):
..is_inbound:
mov eax,value
cmp eax,MIN_BOUND
setae cl
cmp eax,MAX_BOUND+1
sbb cl,0
but the reason i prefer sbb/adc rather than
setcc, is a merely logic one; here we have
a redundancy on infos. CL has the error bound
as like as from the Carry.
Cheers,
--
.:hopcode[marc:rainer:kranz]:.
x64 Assembly Lab
http://sites.google.com/site/x64lab
|
|
0
|
|
|
|
Reply
|
hopcode
|
3/26/2011 12:24:03 AM
|
|
|
5 Replies
233 Views
(page loaded in 0.082 seconds)
|