Advertisement
cutecoder

Checkers in x86_64 assembly

Aug 19th, 2023 (edited)
207
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
ASM (NASM) 3.87 KB | Source Code | 0 0
  1. section .data
  2.     grid: times 32 db 0
  3.     turn: db 0
  4.  
  5. section .text
  6.     global  _start
  7.  
  8. _start:
  9. ; ===== Setup =====
  10.     ; White begins
  11.     mov [turn], byte 1
  12.     ; Setup white pieces
  13.     mov [grid +  0], byte 1
  14.     mov [grid +  1], byte 1
  15.     mov [grid +  2], byte 1
  16.     mov [grid +  3], byte 1
  17.     mov [grid +  4], byte 1
  18.     mov [grid +  5], byte 1
  19.     mov [grid +  6], byte 1
  20.     mov [grid +  7], byte 1
  21.     mov [grid +  8], byte 1
  22.     mov [grid +  9], byte 1
  23.     mov [grid + 10], byte 1
  24.     mov [grid + 11], byte 1
  25.     ; Setup black pieces
  26.     mov [grid + 20], byte 2
  27.     mov [grid + 21], byte 2
  28.     mov [grid + 22], byte 2
  29.     mov [grid + 23], byte 2
  30.     mov [grid + 24], byte 2
  31.     mov [grid + 25], byte 2
  32.     mov [grid + 26], byte 2
  33.     mov [grid + 27], byte 2
  34.     mov [grid + 28], byte 2
  35.     mov [grid + 29], byte 2
  36.     mov [grid + 30], byte 2
  37.     mov [grid + 31], byte 2
  38. ; =================
  39.  
  40. ; TODO: Print inital grid
  41.  
  42. .game_loop:
  43. ; TODO: Get user input
  44.  
  45. ; TODO: Check if input is valid
  46.  
  47.     ; Example:
  48.     mov al, 9       ; From square
  49.     mov bl, 14      ; To square
  50.  
  51. ; ===== Check if input is playable and play the move =====
  52. ; al - Source square index
  53. ; bl - Destination square index
  54. ; dl - Difference of al and bl
  55. ; r8 - Source square pointer
  56. ; r9 - Destination square pointer
  57. ; r10 - Source square row
  58. ; r11 - Source square column
  59. ; r12 - Square in the middle of source and destination (if applicable)
  60.  
  61.     ; Check if the target square is not occupied
  62.     movzx   r8, al
  63.     movzx   r9, bl
  64.     add r8, grid
  65.     add r9, grid
  66.     cmp [r9], byte 0    ; check if destination is empty
  67.     jne .game_loop  ; jump if it's occupied
  68.  
  69.     mov dl, al
  70.     sub dl, bl
  71.     ; These are always valid, no matter where the square is
  72.     cmp dl, -4
  73.     je  .move
  74.     cmp dl,  4
  75.     je  .move
  76.  
  77.     ; Now there comes an inconsistency where squares in odd cells
  78.     ; have the valid distance -3 and 5 but not 3 and -5
  79.     ; That's why we check for an even or odd row
  80.     movzx   r10, al     ; r10 - row index
  81.     shr r10, 2      ; Divide by 4
  82.     test    r10, 1
  83.     jz  .check_even_row ; Jump if even
  84.  
  85. .check_odd_row:
  86.     cmp dl, -3
  87.     je  .move
  88.     cmp dl,  5
  89.     je  .move
  90.     jmp .check_double
  91.  
  92. .check_even_row:
  93.     cmp dl,  3
  94.     je  .move
  95.     cmp dl, -5
  96.     je  .move
  97.  
  98. .check_double:
  99.     movzx   r11, al
  100.     ; Note: Modulo can be fully replaced with and only when
  101.     ; the modulo operand (4 in this case) is a power of two.
  102.     and r11, 0x3    ; Modulo with 4
  103.     ; if(row <= 1 || col <= 1)
  104.     cmp r10, 1
  105.     setle   ah
  106.     cmp r11, 1
  107.     setle   bh
  108.     or  ah, bh
  109.     jz  .not_check_neg9
  110.  
  111. .check_neg9:
  112.     cmp dl, -9
  113.     je  .check_move_double
  114.  
  115. .not_check_neg9:
  116.     ; if(row <= 1 || col >= 6)
  117.     cmp r10, 1
  118.     setle   ah
  119.     cmp r11, 6
  120.     setge   bh
  121.     or  ah, bh
  122.     jz  .not_check_neg7
  123.  
  124. .check_neg7:
  125.     cmp dl, -7
  126.     je  .check_move_double
  127.  
  128. .not_check_neg7:
  129.     ; if(row >= 6 || col <= 1)
  130.     cmp r10, 6
  131.     setge   ah
  132.     cmp r11, 1
  133.     setle   bh
  134.     or  ah, bh
  135.     jz  .not_check_neg7
  136.  
  137. .check_pos7:
  138.     cmp dl,  7
  139.     je  .check_move_double
  140.  
  141. .not_check_pos7:
  142.     ; if(row >= 6 || col >= 6)
  143.     cmp r10, 6
  144.     setge   ah
  145.     cmp r11, 1
  146.     setle   bh
  147.     or  ah, bh
  148.     jz  .not_check_pos9
  149.  
  150. .check_pos9:
  151.     cmp dl,  9
  152.     je  .check_move_double
  153.  
  154. .not_check_pos9:
  155.  
  156.     ; If we reach this point, the move is not playable
  157.     jmp .game_loop
  158.  
  159. ; Additional check to see if the piece in the middle is an enemy
  160. .check_move_double:
  161.     mov ch, [turn]
  162.     ; Get the middle piece
  163.     ; r14 = ((row ^ 1) + source index + destination index) / 2
  164.     mov r13, r10
  165.     xor r13, 1
  166.     movzx   r14, al
  167.     movzx   r15, bl
  168.     add r14, r15
  169.     add r14, r13
  170.     shr r14, 1
  171.     ; cl = grid[r14] & 0x3
  172.     add r14, grid
  173.     mov cl, [r14]
  174.     and cl, 0x3
  175.     jz  .game_loop  ; The middle is not occupied
  176.     xor ch, cl
  177.     jz  .game_loop  ; The piece in the middle is of the same color
  178.  
  179.     mov [r12], byte 0   ; Clear the middle piece
  180.  
  181. .move:
  182.     mov al, [r8]
  183.     mov [r9], al
  184.     mov [r8], byte 0
  185.  
  186. ; ================================================
  187.  
  188. ; TODO: Print grid
  189.  
  190. ; TODO: Check for win
  191.  
  192.     jmp .game_loop
  193.  
  194.     ; Exit the program
  195.     mov rax, 60             ; syscall number for sys_exit
  196.     xor rdi, rdi            ; exit code 0
  197.     syscall
  198.  
Tags: assembly
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement