Home * Organizations * ICGA * Investigations * Rybka Controversy * Pre-Fruit Rybka and Crafty * Rybka-Crafty Evidence
Next >

by Mark Watkins

Code to avoid en passant when using obsolete Edwards tablebases.

Crafty 19.0 iterate.c
  if (TotalWhitePawns && TotalBlackPawns) {
    if (FileDistance(wpawn,bpawn) == 1) {
      if(((Rank(wpawn)==RANK2) && (Rank(bpawn)>RANK3)) ||
         ((Rank(bpawn)==RANK7) && (Rank(wpawn)<RANK6)) ||
         EnPassant(1)) TB_use_ok=0;
Note that the above code is quite particular to KP vs KP (it will fail for KPP vs KP due to FirstOne usage) and avoiding en passant troubles.

Here is disassembly from a pre-Beta Rybka by Mark Watkins, as a text file or here directly:
0x0044cad2:  mov    0x6b8d54,%eax     # global pointer
0x0044cad7:  mov    0xb10(%eax),%cl   # load TotalWhitePawns
0x0044cadd:  add    $0x4,%esp
0x0044cae2*  movl   $0x1,-0x1c(%ebp)  # set TB_use_OK to 1
0x0044cae0:  test   %cl,%cl           # if TotalWhitePawns
0x0044cae9:  je     0x44cbab
0x0044caef:  mov    0xb11(%eax),%cl   #    && TotalBlackPawns
0x0044caf5:  test   %cl,%cl
0x0044caf7:  je     0x44cbab
0x0044cafd:  mov    0xa78(%eax),%edx    # load WhitePawns (32 bits)
0x0044cb03:  mov    0xa7c(%eax),%eax    # load WhitePawns (other 32)
0x0044cb09:  mov    %edx,-0x8(%ebp)
0x0044cb0c:  mov    %eax,-0x4(%ebp)
0x0044cb0f:  bsf    -0x8(%ebp),%edx     # FirstOne for WhitePawns
0x0044cb13:  mov    $0x0,%eax
0x0044cb18:  jne    0x44cb2a
0x0044cb1a:  bsf    -0x4(%ebp),%edx
0x0044cb1e:  mov    $0x20,%eax
0x0044cb23:  jne    0x44cb2a
0x0044cb25:  mov    $0x20,%edx
0x0044cb2a:  add    %edx,%eax
0x0044cb2c:  mov    %eax,%ebx           # store FirstOne in ebx (wpawn)
0x0044cb2e:  mov    0x6b8d54,%eax       # reload global pointer
0x0044cb33:  mov    0xa80(%eax),%ecx    # load Black Pawns (32 bits)
0x0044cb39:  mov    0xa84(%eax),%edx    # load Black Pawns (other 32)
0x0044cb3f:  mov    %ecx,-0x8(%ebp)
0x0044cb42:  mov    %edx,-0x4(%ebp)
0x0044cb45:  bsf    -0x8(%ebp),%edx     # FirstOne for BlackPawns
0x0044cb49:  mov    $0x0,%eax
0x0044cb4e:  jne    0x44cb60
0x0044cb50:  bsf    -0x4(%ebp),%edx
0x0044cb54:  mov    $0x20,%eax
0x0044cb59:  jne    0x44cb60
0x0044cb5b:  mov    $0x20,%edx
0x0044cb60:  add    %edx,%eax
0x0044cb62:  mov    %eax,%ecx           # store FirstOne in ecx (bpawn)
0x0044cb64:  mov    %ecx,%edx
0x0044cb66:  and    $0x7,%edx           # file of bpawn
0x0044cb69:  mov    %ebx,%eax
0x0044cb6b:  and    $0x7,%eax           # file of wpawn
0x0044cb6e:  sub    %edx,%eax           # compute distance
0x0044cb70:  cltd
0x0044cb71:  xor    %edx,%eax
0x0044cb73:  sub    %edx,%eax           # absolute value of distance
0x0044cb75:  cmp    $0x1,%eax           # if FileDistance is 1
0x0044cb78:  mov    0x6b8d54,%eax [rereload global pointer]
0x0044cb7d:  jne    0x44cbab
0x0044cb7f:  sar    $0x3,%ebx           # get Rank of wpawn
0x0044cb82:  cmp    $0x1,%ebx           # if rank is RANK2
0x0044cb85:  jne    0x44cb91
0x0044cb87:  mov    %ecx,%edx           # copy bpawn to edx
0x0044cb89:  and    $0xfffffff8,%edx    # get the rank of it
0x0044cb8c:  cmp    $0x10,%edx          # if the rank exceeds RANK3
0x0044cb8f:  jg     0x44cba8            # set TB_use_ok = 0 (@0x44cba8)
0x0044cb91:  and    $0xfffffff8,%ecx    # get Rank of bpawn
0x0044cb94:  cmp    $0x30,%ecx          # if rank is RANK7
0x0044cb97:  jne    0x44cb9e
0x0044cb99:  cmp    $0x5,%ebx           # and Rank(wpawn) is < RANK6
0x0044cb9c:  jl     0x44cba8            # set TB_use_ok = 0 (@0x44cba8)
0x0044cb9e:  mov    0x10b(%eax),%cl     # load EnPassant(1) [1 is the ply]
0x0044cba4:  test   %cl,%cl             # if there is no ep target
0x0044cba6:  je     0x44cbab            # skip the next instruction
0x0044cba8:  mov    %esi,-0x1c(%ebp)    # [sets TB_use_ok = 0]
0x0044cbab:  mov    0x6b0951,%cl

What links here?

Up one level