Need MSVC with assembler file help

Discussion of chess software programming and technical issues.

Moderators: hgm, Rebel, chrisw

mar
Posts: 2554
Joined: Fri Nov 26, 2010 2:00 pm
Location: Czech Republic
Full name: Martin Sedlak

Re: Need MSVC with assembler file help

Post by mar »

Michael Sherwin wrote: Mon Mar 18, 2019 9:51 pm Partial success.

New sample code.

Code: Select all

#pragma pack (push, 1)
typedef struct {
  int sqr;
  int typ;          // the type of piece, WP ... BK
  int clr;
  int prv;          // the previous on board piece
  int nxt;          // the next on board piece  
  int val;          // the value of the piece
} ps;               // piece-structure 

typedef struct {
  int castle;
  int epsq;
} ss;               // search-structure  

typedef struct {
  int wtm;          // white-to-move
  int ply;          // search ply
  int castle;       // castling status
  int epsq;         // capture e.p. square if any
  int fifty;
  int board[64];
  ps  p[40];        // index piece array 
  ss  s[100];       // search stack 
} ts;
#pragma pack (pop)

ts *t = new ts;

extern "C" int MoveGen(ts *);

int main() {
  int code;

  code = MoveGen(t);
  code = t->p[0].nxt;
}
Since you use all ints (32-bit), there should be no need to use pragma pack(1). Pragma pack is evil, don't use it :)
You can always reorder the structs so that you don't need anything fancy.

Anyway I'm glad it works for you now.

One last thing: don't use pragma pack, really :) Ever.
It should be removed from all compilers and its spec buried 10km underground :)
Martin Sedlak
Michael Sherwin
Posts: 3196
Joined: Fri May 26, 2006 3:00 am
Location: WY, USA
Full name: Michael Sherwin

Re: Need MSVC with assembler file help

Post by Michael Sherwin »

mar wrote: Tue Mar 19, 2019 12:57 am
Michael Sherwin wrote: Mon Mar 18, 2019 9:51 pm Partial success.

New sample code.

Code: Select all

#pragma pack (push, 1)
typedef struct {
  int sqr;
  int typ;          // the type of piece, WP ... BK
  int clr;
  int prv;          // the previous on board piece
  int nxt;          // the next on board piece  
  int val;          // the value of the piece
} ps;               // piece-structure 

typedef struct {
  int castle;
  int epsq;
} ss;               // search-structure  

typedef struct {
  int wtm;          // white-to-move
  int ply;          // search ply
  int castle;       // castling status
  int epsq;         // capture e.p. square if any
  int fifty;
  int board[64];
  ps  p[40];        // index piece array 
  ss  s[100];       // search stack 
} ts;
#pragma pack (pop)

ts *t = new ts;

extern "C" int MoveGen(ts *);

int main() {
  int code;

  code = MoveGen(t);
  code = t->p[0].nxt;
}
Since you use all ints (32-bit), there should be no need to use pragma pack(1). Pragma pack is evil, don't use it :)
You can always reorder the structs so that you don't need anything fancy.

Anyway I'm glad it works for you now.

One last thing: don't use pragma pack, really :) Ever.
It should be removed from all compilers and its spec buried 10km underground :)
:lol: I have been reading about the evil pragma pack. Anyway, once I got it working the way I had originally intended I switched over to SOA. You were right. It is a win win. Much easier to code and faster! :D
If you are on a sidewalk and the covid goes beep beep
Just step aside or you might have a bit of heat
Covid covid runs through the town all day
Can the people ever change their ways
Sherwin the covid's after you
Sherwin if it catches you you're through
Michael Sherwin
Posts: 3196
Joined: Fri May 26, 2006 3:00 am
Location: WY, USA
Full name: Michael Sherwin

Re: Need MSVC with assembler file help

Post by Michael Sherwin »

I had to make some minor changes and the white rook move generator is working.

Code: Select all

t struc
  wtm    dd ?          
  ply    dd ?          
  castle dd ?       
  epsq   dd ?         
  fifty  dd ?
  mli    dd ?
  sqr    dd 40 dup (?)
  typ    dd 40 dup (?)
  clr    dd 40 dup (?)
  prv    dd 40 dup (?)
  nxt    dd 40 dup (?)
  val    dd 40 dup (?)
  board  dd 65 dup (?)
  mlfs   dd 120 dup (?)
  mlts   dd 120 dup (?) 
t ends

extern r:dword
extern tosq:dword
extern nxsq:dword
extern nxdr:dword


.data
  
  ; piece struc to look in to get first piece 
  first dd 2 dup (20, 0)

  ; piece type move function
  ptmf  dq wpmf, wnmf, wbmf, wrmf, wqmf, wkmf, wckf, wcqf, wter,
           bpmf, bnmf, bbmf, brmf, bqmf, bkmf, bckf, bcqf, bter

  ; white rook do function
  wrdf  dq wrrm,
           wrnd, wrnd, wrnd, wrnd, wrnd, wrnd, wrnd, wrnd,
           wrnd, wrnd, wrnd, wrnd, wrnd, wrnd, wrnd, wrnd,
           nxtp, 0, 0, 0,
           wrrc, wrrc, wrrc, wrrc, wrrc, wrrc, wrrc, wrrc,
           wrrc, wrrc, wrrc, wrrc, wrrc, wrrc, wrrc, errr

.code

errr::                                         ; if opposing king is captured, since it is pseudo move generation
  mov eax, 0                               ; white king is always index 16
  ret                                           ; black king is always index 36 

MoveGen proc
  xor r11, r11                               ; the index into the generated move list
  mov eax, [rcx].t.wtm                ; side to move
  mov edx, first[rax*4]                 ; the dummy piece index still on the board
nxtp::                                         ; the next piece index
  mov edx, [rcx].t.nxt[rdx*4]        ; ""
  mov eax, [rcx].t.typ[rdx*4]        ; the piece type
  jmp ptmf [rax*8]                       ; jump through the piece type move function

wpmf::
wnmf::
  
wbmf::
wrmf::                                         ; white rook move function
  mov r8d,  [rcx].t.sqr[rdx*4]         ; the piece square
  mov r9d,  r[r8*4]                         ; location in the move generation table for a R on square
  mov r10d, tosq[r9*4]                   ; the first to square
  mov eax, [rcx].t.board[r10*4]      ; the value on the board at the to square
  jmp wrdf[rax*8]                          ; jump through the white rook do function

wrrm::                                          ; white rook record move
  mov [rcx].t.mlfs[r11*4], r8d         ; save from square
  mov [rcx].t.mlts[r11*4], r10d       ; save to square
  inc r11                                        ; point to next move list cell
  mov r9d, nxsq[r9*4]                     ; get the next square index from the generation move list
  mov r10d, tosq[r9*4]                    ; get the square
  mov eax, [rcx].t.board[r10*4]       ; the value on the board at the to square
  jmp wrdf[rax*8]                            ; jump through the white rook do function

wrrc::                                            ; White rook record move 
  mov [rcx].t.mlfs[r11*4], r8d          ; save fs
  mov [rcx].t.mlts[r11*4], r10d        ; save ts
  inc r11                                         ; advance the generated move list index

wrnd::                                            ; white rook next direction 
  mov r9d, nxdr[r9*4]                      ; get the index
  mov r10d, tosq[r9*4]                     ; get the square
  mov eax, [rcx].t.board[r10*4]        ; get what's on the board at square
  jmp wrdf[rax*8]                            ; jump through white rook do function
  
wqmf::
wkmf::
wckf::
wcqf::
wter::
bpmf::
bnmf::
bbmf::
brmf::
bqmf::
bkmf::
bckf::
bcqf::
bter::


  ret
MoveGen endp

end
This I consider to be the first mile marker on this long trip. The first mile was all up hill. It will be easier from here on. For now I'm using all integers. After it is running outside the debugger I will try making some of the data, bytes.
If you are on a sidewalk and the covid goes beep beep
Just step aside or you might have a bit of heat
Covid covid runs through the town all day
Can the people ever change their ways
Sherwin the covid's after you
Sherwin if it catches you you're through
Michael Sherwin
Posts: 3196
Joined: Fri May 26, 2006 3:00 am
Location: WY, USA
Full name: Michael Sherwin

Re: Need MSVC with assembler file help

Post by Michael Sherwin »

The white knight move generator was super easy.

Code: Select all

; white knight do function
  wndf  dq wnrm,
           wnnd, wnnd, wnnd, wnnd, wnnd, wnnd, wnnd, wnnd,
           wnnd, wnnd, wnnd, wnnd, wnnd, wnnd, wnnd, wnnd,
           nxtp, 0, 0, 0,
           wnrm, wnrm, wnrm, wnrm, wnrm, wnrm, wnrm, wnrm,
           wnrm, wnrm, wnrm, wnrm, wnrm, wnrm, wnrm, errr
           
 wnmf::
  mov r8d,  [rcx].t.sqr[rdx*4]
  mov r9d,  n[r8*4]
  mov r10d, tosq[r9*4]
  mov eax, [rcx].t.board[r10*4]
  jmp wndf[rax*8] 
  
wnrm::
  mov [rcx].t.mlfs[r11*4], r8d
  mov [rcx].t.mlts[r11*4], r10d
  inc r11
wnnd::
  mov r9d, nxsq[r9*4]
  mov r10d, tosq[r9*4]
  mov eax, [rcx].t.board[r10*4]
  jmp wndf[rax*8]           
I won't show the bishop, king or queen as they will be just like the rook and knight. The pawns should be interesting though.
If you are on a sidewalk and the covid goes beep beep
Just step aside or you might have a bit of heat
Covid covid runs through the town all day
Can the people ever change their ways
Sherwin the covid's after you
Sherwin if it catches you you're through
Michael Sherwin
Posts: 3196
Joined: Fri May 26, 2006 3:00 am
Location: WY, USA
Full name: Michael Sherwin

Re: Need MSVC with assembler file help

Post by Michael Sherwin »

Probably my last update. I made a design decision to do the least work possible in the mg. That is why in the following pawn code I only generate one move forward. The idea is why do all that extra work now when there might be an early cut. On a pawn move then a double move can be checked for as well as queening. And cep can be checked for separately from the pawn code anyway. Nothing is set in stone especially when it comes to pawns because for now I just want something up and running while staying as close to the original. I'll optimize later. Here is the pawn code.

Code: Select all

  ; white pawn do function
  wpdf  dq wpnd,
           wpnd, wpnd, wpnd, wpnd, wpnd, wpnd, wpnd, wpnd,
           wnnd, wpnd, wpnd, wpnd, wpnd, wpnd, wpnd, wpnd,
           wpmm, 0, 0, 0,
           wprm, wprm, wprm, wprm, wprm, wprm, wprm, wprm,
           wprm, wprm, wprm, wprm, wprm, wprm, wprm, errr

  ; white pawn terminus function
  wptf  dq wpam,
           nxtp, nxtp, nxtp, nxtp, nxtp, nxtp, nxtp, nxtp,
           nxtp, nxtp, nxtp, nxtp, nxtp, nxtp, nxtp, nxtp,
           0, 0, 0, 0,
           nxtp, nxtp, nxtp, nxtp, nxtp, nxtp, nxtp, nxtp,
           nxtp, nxtp, nxtp, nxtp, nxtp, nxtp, nxtp, nxtp
           
 ; WHITE PAWN MOVE FUNCTION
wpmf::
  mov r8d,  [rcx].t.sqr[rdx*4]
  mov r9d,  wp[r8*4]
  mov r10d, tosq[r9*4]
  mov eax, [rcx].t.board[r10*4]
  jmp wpdf[rax*8] 
  
wprm:: ; record move
  mov [rcx].t.mlfs[r11*4], r8d
  mov [rcx].t.mlts[r11*4], r10d
  inc r11
wpnd:: ; process next direction
  mov r9d, nxsq[r9*4]
  mov r10d, tosq[r9*4]
  mov eax, [rcx].t.board[r10*4]
  jmp wpdf[rax*8] 

wpmm:: ; gen one square forward
  mov r10, r8 
  add r10, 8 ; it is by default on the board so no need for jumptable 
  mov eax, [rcx].t.board[r10*4]
  jmp wptf[rax*8]

wpam:: ; white pawn add move
  mov [rcx].t.mlfs[r11*4], r8d
  mov [rcx].t.mlts[r11*4], r10d
  inc r11
  mov edx, [rcx].t.nxt[rdx*4]
  mov eax, [rcx].t.typ[rdx*4]
  jmp ptmf [rax*8]          
So now all the pieces for both sides are done. One more thing of note is that castling is done with pseudo pieces. They do not have an index on the board but they do have a piece struct. The WK is linked to WCK which is linked to WCQ which is linked to WTER (white terminator) which is also a pseudo piece. When traversing the linked piece structures their respective functions are jumped to thru the jumptables.

I hope someone found this exercise interesting! :D
If you are on a sidewalk and the covid goes beep beep
Just step aside or you might have a bit of heat
Covid covid runs through the town all day
Can the people ever change their ways
Sherwin the covid's after you
Sherwin if it catches you you're through