.arch core2 .include "src/include/macros.inc" .include "src/include/stdfun.inc" .equ TRUE, 1 .equ FALSE, 0 .section .data player_seq: .byte 0,0,0,0,0,0,0,0 psptr: .quad player_seq .align 16 comp_seq: .byte 0,0,0,0,0,0,0,0 csptr: .quad comp_seq .align 16 game_seq: .byte 0,0,0,0,0,0,0,0,0 gsptr: .quad game_seq .align 16 .section .data WINT: .byte 0x11,0x12,0x13 .byte 0x21,0x22,0x23 .byte 0x31,0x32,0x33 .byte 0x11,0x22,0x33 .byte 0x31,0x22,0x13 .byte 0x11,0x21,0x31 .byte 0x12,0x22,0x32 .byte 0x13,0x23,0x33 WINT_END: .byte 0x11,0x12,0x13,0x21,0x22,0x23,0x31,0x32,0x33,0xff WINT2: .byte 0x11,0x13,0x31,0x33,0xff .byte 0x12,0x21,0x22,0x23,0x32,0xff .align 16 TX: TX.r1: .byte '|',' ','|',' ','|',' ','|',0x0a TX.r2: .byte '|',' ','|',' ','|',' ','|',0x0a TX.r3: .byte '|',' ','|',' ','|',' ','|',0x0a .byte 0 .align 16 PIN: .byte 0, 0, 0, 0 .align 16 mapping: .byte 0b00010001 #0x11 .quad TX.r1+1 .byte 0b00010010 #0x12 .quad TX.r1+3 .byte 0b00010011 #0x13 .quad TX.r1+5 .byte 0b00100001 #0x21 .quad TX.r2+1 .byte 0b00100010 #0x22 .quad TX.r2+3 .byte 0b00100011 #0x23 .quad TX.r2+5 .byte 0b00110001 #0x31 .quad TX.r3+1 .byte 0b00110010 #0x32 .quad TX.r3+3 .byte 0b00110011 #0x33 .quad TX.r3+5 .align 16 .section .text .globl _start lookup: # vstup v RDX # adresa tabulky v RSI mov $9, %rcx 8: _bp3: movb (%rsi), %bl cmp %bl, %dl # porovnaj vstup z lookup tabulkou je 1f add $9, %rsi test %rcx, %rcx loopnz 8b mov $-1, %rax # nenasli sme ret 1: xor %rax,%rax movq 1(%rsi), %rax # nasli sme, vysledok v RAX ret redraw: mov $TX, %rdi call dconout ret # NOTE TOhtml - konvertuje do htmlka wvint_p2_errmsg: mconout "Chybny vstup" pushq $TX call dconout wvint_p2: mconout "Hrac [RB]:" mconin $PIN, $3 movb PIN, %al movb PIN+1, %ah _bp2: sub $0x3030, %ax cmp $1, %al jl wvint_p2_errmsg cmp $3, %al jg wvint_p2_errmsg cmp $1, %ah jl wvint_p2_errmsg cmp $3, %ah jg wvint_p2_errmsg mov %al, %bl shl $4, %bl mov %ah, %dl or %bl, %dl movq (psptr), %rbx # deref movb %dl, (%rbx) incq psptr push %rdx mov $mapping, %rsi call lookup movb $'X',(%rax) pop %rax # vystup z funkcie je v RAX = vstup od hraca ret #rule check #rchk7(%rdi = adresa sekvencie) rchk7:#(funguje) push %rbp mov %rsp, %rbp sub $24, %rsp movq %rdi, -8(%rbp) movq $0, -16(%rbp) xor %r15, %r15 79: xor %rdx,%rdx inc %rdx 80: cmp $4, %dl je 2f #---Vsetko skontrolovane, prejde na druhu cast funkcie mov $5, %rcx xor %rbx, %rbx 81: # Rh8= ROW, Rl = COL movzxb (%rdi), %rax _bp8: shl $4, %rax shr $4, %al #ah = row, #al = column movq -16(%rbp), %rbx cmp $1, %rbx jne 811f mov %ah, %al # skontroluje columns 811: cmp %dl, %al je 10f #---nasla sa zhoda 8111: inc %rdi test %rcx, %rcx loopnz 81b 99: jmp 71f 10: inc %r15 cmp $3, %r15 je 1f 71: #--------- tautologia z 99b cmp $0, %rcx jne 11f xor %r15, %r15 inc %dl jmp 12f 11: jmp 8111b 12: movq -8(%rbp), %rdi jmp 80b 2: movq -16(%rbp), %rbx cmp $1, %rbx je 3f movq $1,-16(%rbp) jmp 79b .subx: 3: #---tato cast funkcie skontroluje diagonalne \ _bp9: xor %rdx, %rdx mov $0x11, %dl xor %rbx, %rbx 30: cmp $0x44, %dl je 4f #dalsia cast skontroluje do / movq -8(%rbp), %rdi 300: movzxb (%rdi), %rax test %al,%al jz 4f cmp %dl, %al je 31f inc %rdi jmp 300b 31: inc %rbx cmp $3, %rbx je 1f add $0x11, %dl jmp 30b 4: _bp10: xor %rdx, %rdx mov $0x31, %dl xor %rbx,%rbx 40: cmp $0x04, %dl je 0f movq -8(%rbp), %rdi 400: movzxb (%rdi), %rax test %al,%al jz 0f cmp %dl, %al je 41f inc %rdi jmp 400b 41: inc %rbx cmp $3, %rbx je 1f add $0x01, %dl sub $0x10, %dl jmp 40b 0: mov $0, %rax jmp 5f 1: mov $1, %rax 5: add $24, %rsp mov %rbp, %rsp pop %rbp ret # cpu "ai" komp:#(%rax = byte od hraca) #NOTE skopirovat WORD z WINT do ax a permutovat cez celu tabulku po 1 bajte push %rbp mov %rsp,%rbp sub $8, %rsp mov gsptr, %rdi movb (%rdi), %dl # %al = uz ma byte mov $WINT, %rdi # %rdi = cielova adresa # %al = hladany byte xor %rcx,%rcx 8: movb (%rdi), %bl test %bl,%bl jz 1f test %al,%al jz 1f cmp %al, %bl je 1f inc %rdi inc %rcx jmp 8b 1: mov %rcx, %rax # %rax = index kde sa nasiel byte # %rax,%rcx = index byte-u 8: inc %rax movb WINT(%rax), %dl movq %rdx, -8(%rbp) mov $mapping, %rsi call lookup movb (%rax), %dl cmp $'X',%dl jne 0f #--- ak je policko obsadene hracom mov %rcx,%rax jmp 8b 0: movb $'O',(%rax) movq -8(%rbp), %rax # %rax (%dl) = tah ktory spravil pocitac add $8, %rsp mov %rbp,%rsp pop %rbp ret komp3: push %rbp mov %rsp, %rbp sub $8, %rsp mov $WINT, %rsi #%rax = bajt od hraca 80: movzxb (%rsi), %rdx cmp %al,%dl je 10f #---bajt sa nasiel vo WINT tabulke inc %rsi jmp 80b 10: inc %rsi #inkrement o jedno, dalsie policko vo WINT cmp $WINT_END, %rsi jle 11f #---na konci tabulky, hladame dalej movzxb player_seq, %rax jmp komp3 movq %rax, -8(%rbp) movb (%rsi), %bl 20: #bajt od hraca = bajt z WINT tabulky (%al = %bl) inc %bl cmp $0x34, %bl jne 29f mov $TX, %rdi 27: movzxb (%rdi), %rbx cmp $20, %bl je 28f inc %rdi jmp 27b 28: #%bl = prazdne miesto v TX tabulke #%rdi = adresa prazdneho miesto v TX tabulke mov $mapping, %rsi 281: cmpq 1(%rsi), %rdi je 209f inc %rsi jmp 281b 209: movzxb (%rsi), %rax movb $'O', (%rsi) movq gsptr, %rbx movb %al, (%rbx) movq csptr, %rbx movb %al, (%rbx) incq csptr jmp 5f 29: 100: 11: movzxb (%rsi), %rdx movq gsptr, %rbx movb %dl, (%rbx) movq csptr, %rbx movb %dl, (%rbx) incq csptr push %rdx mov $mapping, %rsi call lookup movb $'O',(%rax) pop %rax #--- %rax = tah kompu 5: mov %rbp, %rsp pop %rbp ret #OBSadenePOLicko obspol:#(%rax = bajt) mov $mapping, %rsi mov %al, %dl call lookup # %rax = adresa volneho policka alebo -1 cmp $-1,%rax # FIXME -1 znamena chybu je 50f cmpb $' ', (%rax) je 50f #nasla sa adresa obsadeneho policka cmpb $'X', (%rax) je 51f cmpb $'O', (%rax) je 51f jmp 5f 50: xor %rax,%rax #ZF = 1 ret 51: xor %rax,%rax xor $1, %rax #ZF = 0 5: ret komp2: #(funkcne piskorkove AI) push %rbp mov %rsp, %rbp # %rax = vstup od hraca pushq $0x1311 # $1 #NOTE: 0x12001311 pushq $0x3133 # $2 pushq $0x2123 # $3 pushq $0x1232 # $4 pushq $0x1333 # $5 pushq $0x1131 # $6 pushq $0x1133 # $7 pushq $0x3113 # $8 mov $9,%rcx 79: mov $player_seq, %rsi mov $player_seq, %rdi inc %rdi dec %rcx test %rcx, %rcx pop %rdx jz 100f #---vsetky permutacie overene, JMP na default 80: movzxb (%rsi), %rax movb (%rdi), %ah 81: cmp %ax,%dx je 10f ror $8, %ax cmp %ax,%dx je 10f inc %rsi cmp $player_seq+5, %rsi jne 80b #NOTE: #ak sme nenasli player bajt a sme na konci sekvencie #tak posunieme %rdi a iterujeme dalej. #toto je nieco ako dvojity for-loop inc %rdi mov $player_seq, %rsi cmp $player_seq+5, %rdi jne 80b #ak ani teraz sme nenasli bajtovi par od hraca #pop-neme dalsi par zo stacku jmp 79b 10: #switch-like rozhodovanie cmp $8, %rcx jne 107f mov $0x22, %rax # / jmp 20f 107: cmp $7, %rcx jne 106f mov $0x22, %rax # \ jmp 20f 106: cmp $6, %rcx jne 105f mov $0x32, %rax # |.. jmp 20f 105: cmp $5, %rcx jne 104f mov $0x12, %rax # ..| jmp 20f 104: cmp $4, %rcx jne 103f mov $0x22, %rax # .|. jmp 20f 103: cmp $3, %rcx jne 102f mov $0x22, %rax # .-. jmp 20f 102: cmp $2, %rcx jne 101f mov $0x32, %rax # .-. jmp 20f 101: cmp $1, %rcx jne 100f mov $0x12, %rax # .-. jmp 20f 100: mov $0x22, %rax 20: push %rax push %rcx call obspol pop %rcx pop %rbx #Logicke AND cmp $0, %rcx jne 22f cmp $0, %rax je 30f #---ak je volne #ak je policko obsadene, a tah je vacsi ako 1 21: movzxb (%r14), %rax inc %r14 call obspol cmp $0,%rax je 30f jmp 21b #---iterujeme dokym nenajdeme jedno policko volne 22: cmp $1, %rax je 79b #---ak je obsadene #---ak nieje obsadene 30: mov %rbx, %rax mov $csptr, %rdi mov (%rdi), %rdi movb %al, (%rdi) mov $gsptr, %rdi mov (%rdi), %rdi movb %al, (%rdi) incq csptr 30: mov $mapping, %rsi mov %al, %dl call lookup movb $'O', (%rax) movzx %dl, %rax 5: mov %rbp, %rsp pop %rbp ret .section .data devrandom: .asciz "/dev/urandom" .section .text komp1: push %rbp mov %rsp, %rbp sub $8, %rsp 10: xor %al,%al # OF = 0 8: mov $devrandom, %rdi mov $1, %rax # %rax = nacitane bajty call otvorsuborbq # iterujeme dokym nedostaneme cislo od 1 do 3 cmp $3, %rax jg 8b cmp $1, %rax jl 8b jo 1f sub $-1, %bl movb %al, -8(%rbp) jmp 8b 1: movb %al, -7(%rbp) movq -8(%rbp), %rax shr $4, %ah #%rax = vysledok, cize 0x11, 0x12, atd. call obspol #Z flag = 1 ak nieje obsadene, 0 = ak je jnz 10b #"rekurzia" mov $mapping, %rsi mov %al, %dl call lookup movb $'O', (%rax) movzx %dl, %rax #%rax = tah ktory spravil pocitac mov %rbp, %rsp pop %rbp ret .section .data hrac1: .quad 'h' hrac2: .quad 'p' obtiaznost: .quad komp1, komp2, komp3 adresa_komp: .quad komp2 .section .text fun_n: mov (%rdi), %rdx sub $0x30, %dl dec %dl mov obtiaznost, %rbx add %dl, %bl mov %rbx, adresa_komp ret fun_z: mov %rdi, %rdx #vstup v %rdi movzx (%rdx), %edx #%dl = bajt 'p' alebo 'h' mov %edx, %eax mov $wvint_p2, %ebx mov adresa_komp, %ecx mov %edx, %edi #%rdi = vstup mov %ebx, %edx cmpxchg %edx, hrac1 cmovz %ecx, %edi cmovnz %ebx, %edi mov %edi, hrac2 #ak sa prvy cmpxchg nerovna, %eax = 'h' mov %ecx, %edx cmpxchg %edx, hrac1 cmovz %ebx, %edi cmovnz %ecx, %edi mov %edi, hrac2 ret dispatch_tabulka: zlozitost_kompu: .ascii "-n" .quad fun_n kdo_zacina: .ascii "-z" .quad fun_z pouzitie_programu: .section .rodata pouzitie_msg: .ascii "piskorky [-n | -z ]\n" .ascii " -n Vstup je cislo od 1 do 3\n" .ascii " reprezentujuce obtiaznost pocitaca\n" .ascii " -z Vstup je znak 'p' alebo 'h'\n" .ascii " zodpovedajuci tomu, kto ide\n" .ascii " prvy. 'h' pre Hrac, 'p' pre\n" .ascii " pocitac\n" .ascii "\n" .ascii " Priklad:\n" .ascii "\n" .ascii " sh> piskorky -n 1 -z p\n" .ascii " | | | |\n" .ascii " Obtiaznost <-----+-+ | |\n" .ascii " Hru zacina pocitac <--+-+\n\x00" .section .text pushq $pouzitie_msg call dconout progend $0 default: movl adresa_komp, %ebx movl %ebx, hrac2 mov $wvint_p2, %ebx movl %ebx, hrac1 ret _start: lea dispatch_tabulka, %rdi mov $2, %rsi mov $10, %rdx mov $pouzitie_msg, %rcx mov $default, %r8 call vstpy mov $TX, %rdi call dconout mov $9, %rcx mov $WINT, %r14 #prefetcht0 mapping gameloop: push %rcx mconout "=======" movq hrac1, %rbx call *%rbx movq hrac1, %rbx cmp $komp2, %rbx je 11f cmp $komp1, %rbx je 11f cmp $komp3, %rbx je 11f jmp 1f 11: call redraw mov $comp_seq, %rdi call rchk7 cmp $TRUE, %rax je vyhra_pocitac 1: mov $gsptr,%rdi movq (%rdi), %rdi movb %al, (%rdi) incq gsptr pop %rcx dec %rcx jz 10f push %rcx _bp5: mov hrac2, %rbx call *%rbx incq gsptr pop %rcx dec %rcx jz 10f push %rcx 10: mov $player_seq, %rdi mov $WINT, %rsi call rchk7 cmp $TRUE, %rax je vyhra_hrac mov $comp_seq, %rdi mov $WINT, %rsi call rchk7 cmp $TRUE, %rax je vyhra_pocitac call redraw pop %rcx test %rcx,%rcx jnz gameloop jmp 7f vyhra_hrac: mconout "=======" call redraw mconout "=======\nVyhral hrac" jmp 7f vyhra_pocitac: mconout "=======" call redraw mconout "=======\nVyhral pocitac" 7: progend $0 .align 16 _progerrend: progend $1 .align 16 .