summaryrefslogtreecommitdiff
path: root/2022/02/part2.asm
blob: fa92ea6e8d845a9f9bde21b88b56d6e0f5c0fb27 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
%include "unistd.asm"
%include "utils.asm"

stdout equ 1

global _start

section .rodata
    JMP_TABLE:   dq  _start.lose, _start.draw, _start.win

section .text
_start:
    mov     rcx, [rsp]              ; Get number of arguments
    mov     rdi, [rsp + rcx * 8]    ; Get last argument

    mov     rax, SYS_access         ; Check if file exists and is readable
    mov     esi, R_OK
    syscall
    test    rax, rax
    jnz     .exit_err

    mov     rax, SYS_open
    xor     esi, esi
    xor     edx, edx
    syscall

    mov     r8d, eax                ; Move fd into r8
    mov     rax, SYS_mmap
    xor     edi, edi                ; Let the kernel choose the address
    mov     rsi, 12288
    mov     rdx, PROT_READ
    mov     r10d, MAP_PRIVATE
    xor     r9d, r9d
    syscall

    cmp     rax, -1                 ; Exit on error
    je      .exit_err

    xor     r8d, r8d              ; score
.loop:
    cmp     byte [rax], 0
    je      .exit
    mov     ecx, [rax]
    add     rax, 4
    mov     edx, ecx
    and     ecx, 0xff
    shr     edx, 2 * 8
    and     edx, 0xff
    sub     ecx, 'A' - 1
    lea     rdi, [JMP_TABLE]
    jmp     [rdi + rdx * 8 - 'X' * 8]

.lose:
%rep    2
    inc     ecx
    mov     edi, ecx
    shr     edi, 2
    or      ecx, edi
    and     ecx, 0b11
%endrep
    add     r8d, ecx

    jmp     .loop

.win:
    inc     ecx
    mov     edi, ecx
    shr     edi, 2
    or      ecx, edi
    and     ecx, 0b11

    add     r8d, 6
    add     r8d, ecx

    jmp     .loop

.draw:
    add     r8d, ecx
    add     r8d, 3
    jmp     .loop

.exit:
    mov     edi, stdout
    mov     esi, r8d
    call    write_ulong

    mov     rax, SYS_exit
    xor     edi, edi
    syscall

.exit_err:
    mov     rax, SYS_exit
    mov     edi, 1
    syscall