September 23, 2020, 01:56:40 pm

News:

Own IWBasic 2.x ? -----> Get your free upgrade to 3.x now.........


I just woundering what's wrong with << 32?

Started by Ficko, June 08, 2007, 06:05:14 am

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

Ficko

I am trying to shift left 32 bits but I am not getting the result.  >:(

After 31 it's seems quit and not doing anything.

DEF My64:UInt64
DEF My32:Uint
My64 = 0xFFFFFFFF
My32 = 0xFFFF
OPENCONSOLE
PRINT "My64:",HEX$(My64)
PRINT "My32:",HEX$(My32)
My64 = My64 << 32
My32 = My32 << 16
PRINT "My64 << 32:",HEX$(My64)," ?????"
PRINT "My32 << 16:",HEX$(My32)," OK"
My64 = My64 << 31
PRINT "My64 << 31:",HEX$(My64)," OK"
DO:UNTIL INKEY$<>""

sapero

June 08, 2007, 07:59:53 am #1 Last Edit: June 08, 2007, 08:14:12 am by sapero
Hello Ficko :)
The problem is, that Paul used shld for left shifting int64's. This command can shift up to 31 bits. Note, you can override this command to fix your problem :)
Code Select
_asm
;   shld esi,edi,cl
;   shl edi,cl

%macro shld 3 ; hi, lo, shift
%push shld
and %3,%3
je %$q
%$a:
sal %2,1
rcl %1,1
dec %3
jnz %$a
%$q:
%define ignore_shl
%pop
%endm


%macro shl 2
%ifdef ignore_shl
%error shl ignored
%undef ignore_shl
%else
shl %1,%2
%endif
%endm
_endasm


Paste these macros just before any shifting (at the top of your source) and run. It shows:
Code Select
My64:FFFFFFFF
My32:FFFF
My64 << 32:FFFFFFFF00000000 ??
My32 << 16:FFFF OK
My64 << 31:8000000000000000 OK

Ionic Wind Support Team

I have discussed this somewhere before..The behaviour was by design.   The compiler uses a true bit shift which doesn't affect the flags register.

The other reason was speed.  I frequently use << for multiplying a value in powers of 2 because it is much faster than multiplying a qword by an integer.  2^31 = 2147483648 so any power of 2 between 0 and 2147483648  can be used to multiply a 64 bit integer much faster than using a mul instruction.  If each bit had to be shifted in a loop then that advanatge is lost.  All part of dealing with 64 bit values on a 32 bit processor ;)

The other solution is of course just to do it twice.  Which would still be faster than using a loop:

My64 = My64 << 31
My64 = My64 << 1

Paul.





Ionic Wind Support Team

Ficko

June 08, 2007, 09:44:59 am #3 Last Edit: June 09, 2007, 03:10:58 am by Ficko
I just wrote my own it's the fastest possible on 32 bit.

But thanks the explanations!

And Sapero patch is a good tutorial for me!  ;)

SUB ShiftL(Target:Uint64,ShiftCount:UInt),Uint64
DEF RetV:Uint64
   _asm
         mov      ecx,[ebp+16]           ;ShiftCount
         mov      eax,[ebp+8]             ;LO
         mov      ebx,[ebp+12]           ;HI
         jecxz   Exit
   cikl:clc                                       ;Clear CF
         rcl         eax,1
         rcl         ebx,1
         loopnz   cikl
   Exit:mov      [ebp-8],eax
         mov      [ebp-4],ebx
   _endasm
RETURN RetV
ENDSUB