That's what i'm doing:bob wrote:...zobrist_signature ^= random[white knight][g5];
zobrist_signature ^= random[white knight][f3];
And I am done. And the order of the above is irrelevant, although I did it in the order the piece moves for clarity. Is that what you are doing? If so, that is how everybody is doing it.
Code: Select all
(mm5 is the actual 64 bit Zobrist key of the position)
mov edi, [esi.nmPezzoP] ; edi = pointer to taken piece
test edi, edi
je em_nopreso ; if zero jump to em_nopreso
pxor mm5, [edi.pLastKey] ; mm5 ^= key(taken, square)
em_nopreso:
mov edi, [edx.mPezzo] ; edi = moved piece
mov ebx, [esi.nmSrc] ; ebx = source square
mov ecx, [esi.nmDst] ; ecx = destination square
movq mm3, [edi.pKey] ; mm3 = key(moved piece)
movq mm2, mm3 ; save key(pezzo) for later use
paddb mm3, [ecx.cKey] ; key(mov.p., dst sq)
paddb mm2, [ebx.cKey] ; key(mov.p., src sq)
movq [edi.pLastKey], mm3 ; save new lastKey for the piece
pxor mm5, mm2 ; mm5 ^= key(piece, src sq)
pxor mm5, mm3 ; mm5 ^= key(piece, dst sq)
(i've omitted some QWORD PTR "cast", for clarity)
paddb mm3, [ecx.cKey] ; key(mov.p., dst sq)
paddb mm2, [ebx.cKey] ; key(mov.p., src sq)
here's where i compute the key(piece, source) and key(piece, destination). For those who don't know what paddb is (not for you): it is an assembly instruction that add two 64 bit values but byte per byte. That means that there are not a carry sum between any 8 bit boundary. I suppose that adding that way two random numbers we still get a good random number, for our purpose. Cache hits similar to those given by Bob can suggest this, i think. Whe can use a word or dword sum as well (qword sum is not available on mmx).
Finally i think that i can use directly my pointers to access the full random keys array but maybe i should do some more operations. Still this way is "elegant", from an assembly programmer point of view, because it requires only 16+64 random values and no extra indexes (piece+square).
Of course i put in pKey member of the piece structure the same random key for piece of the same type. By that way i havent to store the piece type index because i already have the key(piece)=key(type).
Using assembly struct makes the assembly program enough readable as C program, i think... just adding a lot of comment
