The purpose of this thread is to show that the pre-Beta Rybka contained "large chunks" of code from Crafty, but the next segments in EvaluateWinner() get so repetitive that I will elide some details.
Our "friend" the compiler likes to "optimise" here, particularly with the Distance macro. So the pre-Beta Rybka disassembly looks a bit hairy. I also omit the last a/h-file "else" case, as it
.
Code: Select all
0x004016f0: mov 0xb0a(%ecx),%bl # load TotalWhitePieces
[...]
0x00401788: mov 0xb10(%ecx),%al # load TotalWhitePawns
0x0040178e: test %al,%al # if TotalWhitePawns is nonzero
0x00401790: je 0x401bae
0x00401796: mov 0xa78(%ecx),%esi # load WhitePawns bitboard
0x0040179c: mov 0xa7c(%ecx),%edi # ... in 2 steps of course
0x004017a2: mov %esi,%eax
0x004017a4: mov %edi,%edx
0x004017a6: and $0x7e7e7e7e,%eax # AND WhitePawns with not_rook_pawns
0x004017ab: and $0x7e7e7e7e,%edx
0x004017b1: or %edx,%eax
0x004017b3: jne 0x401bab # if result is nonzero, skip the rest
0x004017b9: cmp $0x3,%bl
0x004017bc: jg 0x401bab # if TotalWhitePieces > 3
0x004017c2: jne 0x4017d6 # or (TotalWhitePieces ==3
0x004017c4: mov 0xa88(%ecx),%edx # and WhiteKnights)
0x004017ca: or 0xa8c(%ecx),%edx # [other 32-bit of WhiteKnights]
0x004017d0: jne 0x401bab # then skip the rest
0x004017d6: test %bl,%bl
0x004017d8: jne 0x401804 # if TotalWhitePieces is 0
0x004017da: mov %esi,%eax
0x004017dc: mov %edi,%edx
0x004017de: and $0x1010101,%eax # AND WhitePawns with FILEA filemask
0x004017e3: and $0x1010101,%edx
0x004017e9: or %edx,%eax
0x004017eb: je 0x401804
0x004017ed: mov %esi,%eax
0x004017ef: mov %edi,%edx
0x004017f1: and $0x80808080,%eax # AND WhitePawns with FILEH filemask
0x004017f6: and $0x80808080,%edx
0x004017fc: or %edx,%eax
0x004017fe: jne 0x401bab # if both are nonzero, skip the rest
0x00401804: mov 0xa98(%ecx),%eax # load WhiteBishops
0x0040180a: mov 0xa9c(%ecx),%edx
0x00401810: mov %eax,%ebx
0x00401812: or %edx,%ebx
0x00401814: mov %edx,-0x10(%ebp)
0x00401817: je 0x401896 # if WhiteBishops is nonzero
0x00401819: mov 0xaa0(%ecx),%ebx # load BlackBishops
0x0040181f: mov 0xaa4(%ecx),%edx
0x00401825: mov %ebx,-0xc(%ebp)
0x0040182d: or %edx,%ebx
0x0040182f: jne 0x40184f # if BlackBishops is 0
0x00401828* and $0xaa55aa55,%eax
0x00401831: mov -0x10(%ebp),%edx
0x00401834: and $0xaa55aa55,%edx # AND WhiteBishops with dark_squares
0x0040183a: or %edx,%eax
0x0040183c: mov %edi,%edx
0x0040183e: mov %esi,%eax
0x00401840: je 0x401883 # if result is nonzero
0x00401842: and $0x80808080,%eax # AND WhitePawns with FILEH
0x00401847: and $0x80808080,%edx # else AND WhitePawns with FILEA
0x0040184d: jmp 0x40188e # if result is non-0, skip the rest
0x0040184f: mov -0x10(%ebp),%ebx # else [a BlackBishop exists]
0x00401852: and $0xaa55aa55,%ebx
0x00401858: or %ebx,%eax
0x0040185a: je 0x40187f # if (WhiteBishop & dark_squares)
0x0040185c: mov -0xc(%ebp),%eax
0x0040185f: and $0xaa55aa55,%eax
0x00401864: and $0xaa55aa55,%edx
0x0040186a: or %edx,%eax
0x0040186c: jne 0x40187f # and !(BlackBishops & dark_squares)
0x0040186e: mov %esi,%eax
0x00401870: mov %edi,%edx
0x00401872: and $0x80808080,%eax # AND WhitePawns with FILEH
0x00401877: and $0x80808080,%edx # else AND WhitePawns with FILA
0x0040187d: jmp 0x40188e # if result is non-0, skip the rest
0x0040187f: mov %esi,%eax
0x00401881: mov %edi,%edx
0x00401883: and $0x1010101,%eax [AND with FILEA, see 401840 above]
0x00401888: and $0x1010101,%edx
0x0040188e: or %edx,%eax
0x00401890: jne 0x401bab
0x00401896: mov %esi,%ebx # So, blind bishops are applicable...
0x00401898: and $0x1010101,%ebx
0x0040189e: mov %edi,%eax
0x004018a0: and $0x1010101,%eax # AND WhitePawns with FILEA
0x004018a5: mov %ebx,%edx
0x004018a7: or %eax,%edx
0x004018a9: mov %eax,-0x18(%ebp)
0x004018ac: je 0x4018c8
0x004018ae: mov %esi,%eax
0x004018b0: mov %edi,%edx
0x004018b2: and $0x80808080,%eax # AND WhitePawns with FILEH
0x004018b7: and $0x80808080,%edx
0x004018bd: or %edx,%eax
0x004018bf: jne 0x401bab # if neither is zero, skip the rest
0x004018c5: mov -0x18(%ebp),%eax
0x004018c8: mov %ebx,%edx # about to split into two cases...
0x004018ca: or %eax,%edx
0x004018cc: je 0x401a34 # if (WhitePawns & file_mask[FILEA])
0x004018d2: movsbl 0xb09(%ecx),%edi # load BlackKingSQ
0x004018d9: mov %edi,%eax
0x004018db: sar $0x3,%eax
0x004018de: sub $0x7,%eax # compute Distance(BlackKingSq, A8)
0x004018e1: cltd
0x004018e2: mov %eax,%esi
0x004018e4: xor %edx,%esi
0x004018e6: mov %edi,%eax
0x004018e8: and $0x7,%eax
0x004018eb: sub %edx,%esi
0x004018ed: cltd
0x004018ee: xor %edx,%eax
0x004018f0: sub %edx,%eax
0x004018f2: cmp %esi,%eax
0x004018f4: mov %eax,0x8(%ebp)
0x004018f7: jg 0x4018fc
0x004018f9: mov %esi,0x8(%ebp) # distance is now in 0x8(%ebp)
0x004018fc: cmpl $0x1,0x8(%ebp) # compare this distance to 1
0x00401900: jle 0x401ba7 # if distance <= 1
0x00401ba7* andl $0x2,-0x4(%ebp) # AND "can_win" with 2
0x00401bab* mov -0x4(%ebp),%esi # and ignore the rest
0x00401906: movsbl 0xb08(%ecx),%edi # else load WhiteKingSQ
0x0040190d: mov %edi,%eax
0x0040190f: sar $0x3,%eax
0x00401912: sub $0x7,%eax
0x00401915: cltd
0x00401916: mov %eax,%esi
0x00401918: xor %edx,%esi
0x0040191a: mov %edi,%eax
0x0040191c: and $0x7,%eax
0x0040191f: sub %edx,%esi
0x00401921: cltd
0x00401922: xor %edx,%eax
0x00401924: sub %edx,%eax
0x00401926: cmp %esi,%eax
0x00401928: jle 0x40192c
0x0040192a: mov %eax,%esi
0x0040192c: mov -0x18(%ebp),%eax # have Distance(WhiteKingSQ,A8)
0x0040192f: mov %ebx,-0x24(%ebp) # now the next Distance
0x00401932: mov %eax,-0x20(%ebp)
0x00401935: bsf -0x24(%ebp),%edx # get LastOne(WhitePawns & FILEA)
0x00401939: mov $0x0,%eax
0x0040193e: jne 0x401950
0x00401940: bsf -0x20(%ebp),%edx
0x00401944: mov $0x20,%eax
0x00401949: jne 0x401950 # HORRORS, the compiler is going
0x0040194b: mov $0x20,%edx # to split the Distance computation
0x00401950: add %edx,%eax # with Max(FileDist,RankDist)
0x00401952: mov 0xa78(%ecx),%edx # and then FileDist as abs(x,y)
0x00401958: mov %eax,%edi # into four different parts...!
0x0040195a: mov 0xa7c(%ecx),%eax
0x00401960: and $0x1010101,%edx
0x00401966: and $0x1010101,%eax
0x0040196b: mov %edx,-0x24(%ebp)
0x0040196e: mov %eax,-0x20(%ebp)
0x00401971: bsf -0x24(%ebp),%edx # get LastOne(WhitePawns & FILEA)
0x00401975: mov $0x0,%eax
0x0040197a: jne 0x40198c
0x0040197c: bsf -0x20(%ebp),%edx
0x00401980: mov $0x20,%eax
0x00401985: jne 0x40198c
0x00401987: mov $0x20,%edx
0x0040198c: add %edx,%eax
0x0040198e: sar $0x3,%eax
0x00401991: sub $0x7,%eax
0x00401994: cltd
0x00401995: mov %eax,%ebx
0x00401997: xor %edx,%ebx
0x00401999: sub %edx,%ebx
0x0040199b: mov %edi,%eax
0x0040199d: and $0x7,%eax
0x004019a0: cltd
0x004019a1: xor %edx,%eax
0x004019a3: sub %edx,%eax
0x004019a5: mov 0xa78(%ecx),%edx
0x004019ab: and $0x1010101,%edx
0x004019b1: cmp %ebx,%eax
0x004019b3: mov 0xa7c(%ecx),%eax
0x004019b9: mov %edx,-0x24(%ebp)
0x004019bc: jle 0x4019e8
0x004019be: and $0x1010101,%eax
0x004019c3: mov %eax,-0x20(%ebp)
0x004019c6: bsf -0x24(%ebp),%edx # get LastOne(WhitePawns & FILEA)
0x004019ca: mov $0x0,%eax
0x004019cf: jne 0x4019e1
0x004019d1: bsf -0x20(%ebp),%edx
0x004019d5: mov $0x20,%eax
0x004019da: jne 0x4019e1
0x004019dc: mov $0x20,%edx
0x004019e1: add %edx,%eax
0x004019e3: and $0x7,%eax
0x004019e6: jmp 0x401a13
0x004019e8: and $0x1010101,%eax
0x004019ed: mov %eax,-0x20(%ebp)
0x004019f0: bsf -0x24(%ebp),%edx # get LastOne(WhitePawns & FILEA)
0x004019f4: mov $0x0,%eax
0x004019f9: jne 0x401a0b
0x004019fb: bsf -0x20(%ebp),%edx
0x004019ff: mov $0x20,%eax
0x00401a04: jne 0x401a0b
0x00401a06: mov $0x20,%edx
0x00401a0b: add %edx,%eax
0x00401a0d: sar $0x3,%eax
0x00401a10: sub $0x7,%eax
0x00401a13: mov 0x8(%ebp),%edi
0x00401a16: cltd
0x00401a19: sub %edx,%eax
0x00401a1b: mov 0x6aa02c,%edx # load wtm
0x00401a21: sub %edx,%esi
0x00401a23: cmp %esi,%edi # if (bkd < wkd-wtm)
0x00401a25: jge 0x401bab
0x00401a2b: sub %edx,%eax
0x00401a2d: cmp %eax,%edi # and (bkd <= pd-wtm)
0x00401a2f: jmp 0x401ba5
0x00401ba5* jg 0x401bab
0x00401ba7* andl $0x2,-0x4(%ebp) # AND "can_win" with 2, skip rest
0x00401a34: movsbl 0xb09(%ecx),%eax # else case 2, the same for H8/FILEH
[...]
The next Crafty code segment does the same as this one, but for Black instead of White. I will spare you the details, and the next post will move on the final 3 conditions in this function.