Code: Select all
; ATTACKED BY BLACK - rax contains the square in question
Atkbyblk proc
mov r8d, wp[rax*4] ; wp indexed by square gives first entry in huge move table
abb1:
mov r9d, tosq[r8*4] ; from tosq[] we get the first destination square
mov r10d, [rcx].t.board[r9*4] ; the index of piece on board - empty squares are 0
mov r10d, [rcx].t.typ[r10*4] ; with the index we can get the piece type
cmp r10, 11 ; compare piece type to black pawn (I need to do some equates so I can use BP)
je abbt ; attacked by black true
mov r8d, nxsq[r8*4] ; if next square r8 is loaded with the next cell
cmp r8, 0 ;no next square
je abbb ; attacked by black bishop?
jmp abb1 ; loop back to get next destination square
abbb:
mov r8d, b[rax*4]
abb2:
mov r9d, tosq[r8*4]
mov r10d, [rcx].t.board[r9*4]
mov r10d, [rcx].t.typ[r10*4]
cmp r10, 13 ; black bishop
je abbt
cmp r10, 15 ; black queen
je abbt
cmp r10, 16 ; black king
je abbt
mov r8d, nxsq[r8*4]
cmp r8, 0
je abbr
jmp abb2
abbr:
mov r8d, r[rax*4]
abb3:
mov r9d, tosq[r8*4]
mov r10d, [rcx].t.board[r9*4]
mov r10d, [rcx].t.typ[r10*4]
cmp r10, 14 ; black rook
je abbt
cmp r10, 15
je abbt
cmp r10, 16
je abbt
mov r8d, nxsq[r8*4]
cmp r8, 0
je abbn
jmp abb3
abbn:
mov r8d, n[rax*4]
abb4:
mov r9d, tosq[r8*4]
mov r10d, [rcx].t.board[r9*4]
mov r10d, [rcx].t.typ[r10*4]
cmp r10, 12 ; black knight
je abbt
mov r8d, nxsq[r8*4]
cmp r8, 0
je abbf
jmp abb4
abbf: ; attacked by black false
xor rax, rax
ret
abbt: ; attacked by black true
mov rax, 1
ret
Atkbyblk endp


The method I decided on is similar to GNUChess 4 except the move tables are perfectly compressed while GNUChess used 64 bytes for every single piece type for every single square. The code above demonstrates how wonderful x64 is with all those volatile registers that need not be preserved and parameters are not passed on the stack unless there are not enough registers. For those that might be interested but never took the leap into assembler I just wanted to demonstrate how easy it can be.
