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$<>""
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 :)
_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:My64:FFFFFFFF
My32:FFFF
My64 << 32:FFFFFFFF00000000 ??
My32 << 16:FFFF OK
My64 << 31:8000000000000000 OK
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.
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