From 63445aa008d5c68aecd6348b5d199f7a37cd1572 Mon Sep 17 00:00:00 2001 From: Simon Holmberg Date: Sun, 30 Nov 2014 15:11:02 +0100 Subject: [PATCH] OK LETS GIT HOLY SHIT --- .session.vim | 79 ++++++ Makefile | 31 +++ cnibbles.S | 744 +++++++++++++++++++++++++++++++++++++++++++++++++++ cnibbles.c | 178 ++++++++++++ helpers.c | 48 ++++ main.c | 33 +++ main.o | Bin 0 -> 3964 bytes nibbles.S | 369 +++++++++++++++++++++++++ start.S | 12 + test.c | 9 + test.s | 85 ++++++ workaround.S | 9 + 12 files changed, 1597 insertions(+) create mode 100644 .session.vim create mode 100644 Makefile create mode 100644 cnibbles.S create mode 100644 cnibbles.c create mode 100644 helpers.c create mode 100644 main.c create mode 100644 main.o create mode 100644 nibbles.S create mode 100644 start.S create mode 100644 test.c create mode 100644 test.s create mode 100644 workaround.S diff --git a/.session.vim b/.session.vim new file mode 100644 index 0000000..0a41f15 --- /dev/null +++ b/.session.vim @@ -0,0 +1,79 @@ +let SessionLoad = 1 +if &cp | set nocp | endif +let s:so_save = &so | let s:siso_save = &siso | set so=0 siso=0 +let v:this_session=expand(":p") +silent only +cd ~/Skolarbete/Prestandaoptimering/Projekt\ 1\ -\ Nibbles +if expand('%') == '' && !&modified && line('$') <= 1 && getline(1) == '' + let s:wipebuf = bufnr('%') +endif +set shortmess=aoO +badd +1 cnibbles.c +badd +1 nibbles.S +argglobal +silent! argdel * +edit nibbles.S +set splitbelow splitright +wincmd _ | wincmd | +vsplit +1wincmd h +wincmd w +set nosplitbelow +set nosplitright +wincmd t +set winheight=1 winwidth=1 +exe 'vert 1resize ' . ((&columns * 137 + 137) / 274) +exe '2resize ' . ((&lines * 60 + 31) / 62) +exe 'vert 2resize ' . ((&columns * 136 + 137) / 274) +argglobal +setlocal fdm=manual +setlocal fde=0 +setlocal fmr={{{,}}} +setlocal fdi=# +setlocal fdl=0 +setlocal fml=1 +setlocal fdn=20 +setlocal fen +silent! normal! zE +let s:l = 23 - ((22 * winheight(0) + 30) / 61) +if s:l < 1 | let s:l = 1 | endif +exe s:l +normal! zt +23 +normal! 042| +wincmd w +argglobal +edit cnibbles.c +setlocal fdm=manual +setlocal fde=0 +setlocal fmr={{{,}}} +setlocal fdi=# +setlocal fdl=0 +setlocal fml=1 +setlocal fdn=20 +setlocal fen +silent! normal! zE +let s:l = 141 - ((41 * winheight(0) + 30) / 60) +if s:l < 1 | let s:l = 1 | endif +exe s:l +normal! zt +141 +normal! 041| +wincmd w +exe 'vert 1resize ' . ((&columns * 137 + 137) / 274) +exe '2resize ' . ((&lines * 60 + 31) / 62) +exe 'vert 2resize ' . ((&columns * 136 + 137) / 274) +tabnext 1 +if exists('s:wipebuf') + silent exe 'bwipe ' . s:wipebuf +endif +unlet! s:wipebuf +set winheight=1 winwidth=20 shortmess=filnxtToO +let s:sx = expand(":p:r")."x.vim" +if file_readable(s:sx) + exe "source " . fnameescape(s:sx) +endif +let &so = s:so_save | let &siso = s:siso_save +doautoall SessionLoadPost +unlet SessionLoad +" vim: set ft=vim : diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..52dd91d --- /dev/null +++ b/Makefile @@ -0,0 +1,31 @@ +# Makefile for the nibbles lab. +# ---> Compile with gamke on BSD systems! <--- + +all: nibbles_asm nibbles_asm_start + +# Rule for compiling C source +.c.o: + gcc -Os -std=c11 -m32 -march=i686 -Wall -g -c $< + +# Rule for compiling assembly source +.s.o: + #as -gstabs $^ -o $@ + gcc -m32 -march=i686 -c $< + + +# C game +nibbles_c: main.o cnibbles.o + gcc -lcurses $^ -o $@ + +# ASM game +nibbles_asm: main.o nibbles.o helpers.o + gcc -m32 -lcurses $^ -o $@ + +# ASM game +nibbles_asm_start: start.o nibbles.o helpers.o + gcc -m32 -lcurses -lc -nostdlib $^ -o $@ + +clean: + rm -f *~ + rm -f *.o + rm -f nibbles_c nibbles_asm nibbles_asm_start diff --git a/cnibbles.S b/cnibbles.S new file mode 100644 index 0000000..dcdb059 --- /dev/null +++ b/cnibbles.S @@ -0,0 +1,744 @@ + .file "cnibbles.c" + .local p_screen + .comm p_screen,8,8 + .text + .globl nib_poll_kbd + .type nib_poll_kbd, @function +nib_poll_kbd: +.LFB0: + .cfi_startproc + pushq %rbp + .cfi_def_cfa_offset 16 + .cfi_offset 6, -16 + movq %rsp, %rbp + .cfi_def_cfa_register 6 + subq $16, %rsp + movq stdscr@GOTPCREL(%rip), %rax + movq (%rax), %rax + movq %rax, %rdi + call wgetch@PLT + movl %eax, -4(%rbp) + movl -4(%rbp), %eax + leave + .cfi_def_cfa 7, 8 + ret + .cfi_endproc +.LFE0: + .size nib_poll_kbd, .-nib_poll_kbd + .section .rodata +.LC0: + .string "%c" + .text + .globl nib_put_scr + .type nib_put_scr, @function +nib_put_scr: +.LFB1: + .cfi_startproc + pushq %rbp + .cfi_def_cfa_offset 16 + .cfi_offset 6, -16 + movq %rsp, %rbp + .cfi_def_cfa_register 6 + subq $16, %rsp + movl %edi, -4(%rbp) + movl %esi, -8(%rbp) + movl %edx, -12(%rbp) + movl -12(%rbp), %edx + movl -4(%rbp), %esi + movl -8(%rbp), %eax + movl %edx, %ecx + leaq .LC0(%rip), %rdx + movl %eax, %edi + movl $0, %eax + call mvprintw@PLT + movq p_screen(%rip), %rax + movq %rax, %rdi + call wrefresh@PLT + leave + .cfi_def_cfa 7, 8 + ret + .cfi_endproc +.LFE1: + .size nib_put_scr, .-nib_put_scr + .globl nib_init + .type nib_init, @function +nib_init: +.LFB2: + .cfi_startproc + pushq %rbp + .cfi_def_cfa_offset 16 + .cfi_offset 6, -16 + movq %rsp, %rbp + .cfi_def_cfa_register 6 + movl $0, %edi + call time@PLT + movl %eax, %edi + call srand@PLT + call initscr@PLT + movq %rax, p_screen(%rip) + call start_color@PLT + movl $0, %edi + call curs_set@PLT + call noecho@PLT + movq p_screen(%rip), %rax + movl $1, %esi + movq %rax, %rdi + call keypad@PLT + movq p_screen(%rip), %rax + movl $1, %esi + movq %rax, %rdi + call nodelay@PLT + popq %rbp + .cfi_def_cfa 7, 8 + ret + .cfi_endproc +.LFE2: + .size nib_init, .-nib_init + .globl nib_end + .type nib_end, @function +nib_end: +.LFB3: + .cfi_startproc + pushq %rbp + .cfi_def_cfa_offset 16 + .cfi_offset 6, -16 + movq %rsp, %rbp + .cfi_def_cfa_register 6 + call endwin@PLT + movl $0, %edi + call exit@PLT + .cfi_endproc +.LFE3: + .size nib_end, .-nib_end + .globl startLength + .bss + .align 4 + .type startLength, @object + .size startLength, 4 +startLength: + .zero 4 + .globl startApples + .align 4 + .type startApples, @object + .size startApples, 4 +startApples: + .zero 4 + .comm currentTick,4,4 + .comm snake,9600,64 + .comm snakeLength,4,4 + .comm snakeX,4,4 + .comm snakeY,4,4 + .comm snakeDirX,4,4 + .comm snakeDirY,4,4 + .comm numApples,4,4 + .text + .globl start_game + .type start_game, @function +start_game: +.LFB4: + .cfi_startproc + pushq %rbp + .cfi_def_cfa_offset 16 + .cfi_offset 6, -16 + movq %rsp, %rbp + .cfi_def_cfa_register 6 + subq $48, %rsp + movl %edi, -36(%rbp) + movl %esi, -40(%rbp) + movl startLength(%rip), %eax + testl %eax, %eax + jne .L7 + movl -36(%rbp), %eax + movl %eax, startLength(%rip) +.L7: + movl startApples(%rip), %eax + testl %eax, %eax + jne .L8 + movl -40(%rbp), %eax + movl %eax, startApples(%rip) +.L8: + movq currentTick@GOTPCREL(%rip), %rax + movl $0, (%rax) + movl -36(%rbp), %edx + movq snakeLength@GOTPCREL(%rip), %rax + movl %edx, (%rax) + movl -40(%rbp), %edx + movq numApples@GOTPCREL(%rip), %rax + movl %edx, (%rax) + call nib_init + movl $0, -20(%rbp) + jmp .L9 +.L10: + movq snakeLength@GOTPCREL(%rip), %rax + movl (%rax), %eax + movl %eax, %ecx + movq snake@GOTPCREL(%rip), %rax + movl -20(%rbp), %edx + movl %ecx, (%rax,%rdx,4) + addl $1, -20(%rbp) +.L9: + cmpl $2399, -20(%rbp) + jbe .L10 + movq snakeX@GOTPCREL(%rip), %rax + movl $30, (%rax) + movq snakeY@GOTPCREL(%rip), %rax + movl $20, (%rax) + movq snakeDirX@GOTPCREL(%rip), %rax + movl $0, (%rax) + movq snakeDirY@GOTPCREL(%rip), %rax + movl $-1, (%rax) + movl $0, -16(%rbp) + jmp .L11 +.L12: + movq snakeX@GOTPCREL(%rip), %rax + movl (%rax), %ecx + movl $-2004318071, %edx + movl %ecx, %eax + mull %edx + movl %edx, %eax + shrl $5, %eax + movl %eax, -8(%rbp) + movl -8(%rbp), %eax + movl %eax, %edx + leal 0(,%rdx,4), %eax + movl %eax, %edx + movl %edx, %eax + sall $4, %eax + subl %edx, %eax + subl %eax, %ecx + movl %ecx, %eax + movl %eax, -8(%rbp) + movq snakeY@GOTPCREL(%rip), %rax + movl (%rax), %edx + movl -16(%rbp), %eax + leal (%rdx,%rax), %ecx + movl $-858993459, %edx + movl %ecx, %eax + mull %edx + movl %edx, %eax + shrl $5, %eax + movl %eax, -4(%rbp) + movl -4(%rbp), %edx + movl %edx, %eax + sall $2, %eax + addl %edx, %eax + sall $3, %eax + subl %eax, %ecx + movl %ecx, %eax + movl %eax, -4(%rbp) + movl -4(%rbp), %eax + sall $2, %eax + movl %eax, %edx + sall $4, %edx + subl %eax, %edx + movl -8(%rbp), %eax + leal (%rdx,%rax), %ecx + movl -16(%rbp), %edx + movq snake@GOTPCREL(%rip), %rax + movl %ecx, %ecx + movl %edx, (%rax,%rcx,4) + addl $1, -16(%rbp) +.L11: + movq snakeLength@GOTPCREL(%rip), %rax + movl (%rax), %eax + cmpl %eax, -16(%rbp) + jb .L12 + movl $0, %edi + call time@PLT + movl %eax, %edi + call srand@PLT + movl $0, -12(%rbp) + jmp .L13 +.L14: + movl $0, %eax + call spawnApple + addl $1, -12(%rbp) +.L13: + movq numApples@GOTPCREL(%rip), %rax + movl (%rax), %eax + cmpl %eax, -12(%rbp) + jb .L14 +.L15: + movl $0, %eax + call tick + movl $0, %eax + call draw + jmp .L15 + .cfi_endproc +.LFE4: + .size start_game, .-start_game + .globl spawnApple + .type spawnApple, @function +spawnApple: +.LFB5: + .cfi_startproc + pushq %rbp + .cfi_def_cfa_offset 16 + .cfi_offset 6, -16 + movq %rsp, %rbp + .cfi_def_cfa_register 6 + subq $16, %rsp + call rand@PLT + movl %eax, %ecx + movl $-2004318071, %edx + movl %ecx, %eax + imull %edx + leal (%rdx,%rcx), %eax + sarl $5, %eax + movl %eax, %edx + movl %ecx, %eax + sarl $31, %eax + subl %eax, %edx + movl %edx, %eax + movl %eax, %edx + leal 0(,%rdx,4), %eax + movl %eax, %edx + movl %edx, %eax + sall $4, %eax + subl %edx, %eax + subl %eax, %ecx + movl %ecx, %eax + movl %eax, -8(%rbp) + call rand@PLT + movl %eax, %ecx + movl $1717986919, %edx + movl %ecx, %eax + imull %edx + sarl $4, %edx + movl %ecx, %eax + sarl $31, %eax + subl %eax, %edx + movl %edx, %eax + sall $2, %eax + addl %edx, %eax + sall $3, %eax + subl %eax, %ecx + movl %ecx, %edx + movl %edx, -4(%rbp) + jmp .L17 +.L18: + call rand@PLT + movl %eax, %ecx + movl $-2004318071, %edx + movl %ecx, %eax + imull %edx + leal (%rdx,%rcx), %eax + sarl $5, %eax + movl %eax, %edx + movl %ecx, %eax + sarl $31, %eax + subl %eax, %edx + movl %edx, %eax + movl %eax, %edx + leal 0(,%rdx,4), %eax + movl %eax, %edx + movl %edx, %eax + sall $4, %eax + subl %edx, %eax + subl %eax, %ecx + movl %ecx, %eax + movl %eax, -8(%rbp) + call rand@PLT + movl %eax, %ecx + movl $1717986919, %edx + movl %ecx, %eax + imull %edx + sarl $4, %edx + movl %ecx, %eax + sarl $31, %eax + subl %eax, %edx + movl %edx, %eax + sall $2, %eax + addl %edx, %eax + sall $3, %eax + subl %eax, %ecx + movl %ecx, %edx + movl %edx, -4(%rbp) +.L17: + movl -4(%rbp), %eax + sall $2, %eax + movl %eax, %edx + sall $4, %edx + subl %eax, %edx + movl -8(%rbp), %eax + addl %eax, %edx + movq snake@GOTPCREL(%rip), %rax + movl %edx, %edx + movl (%rax,%rdx,4), %eax + movl %eax, %edx + movq snakeLength@GOTPCREL(%rip), %rax + movl (%rax), %eax + cmpl %eax, %edx + jb .L18 + movl -4(%rbp), %eax + sall $2, %eax + movl %eax, %edx + sall $4, %edx + subl %eax, %edx + movl -8(%rbp), %eax + addl %eax, %edx + movq snake@GOTPCREL(%rip), %rax + movl %edx, %edx + movl $-1, (%rax,%rdx,4) + leave + .cfi_def_cfa 7, 8 + ret + .cfi_endproc +.LFE5: + .size spawnApple, .-spawnApple + .globl tick + .type tick, @function +tick: +.LFB6: + .cfi_startproc + pushq %rbp + .cfi_def_cfa_offset 16 + .cfi_offset 6, -16 + movq %rsp, %rbp + .cfi_def_cfa_register 6 + subq $16, %rsp + movq currentTick@GOTPCREL(%rip), %rax + movl (%rax), %eax + leal 1(%rax), %edx + movq currentTick@GOTPCREL(%rip), %rax + movl %edx, (%rax) + movl $0, -16(%rbp) + jmp .L20 +.L22: + movq snake@GOTPCREL(%rip), %rax + movl -16(%rbp), %edx + movl (%rax,%rdx,4), %eax + movl %eax, -12(%rbp) + cmpl $0, -12(%rbp) + js .L21 + cmpl $0, -12(%rbp) + js .L21 + movl -12(%rbp), %edx + movq snakeLength@GOTPCREL(%rip), %rax + movl (%rax), %eax + cmpl %eax, %edx + ja .L21 + movq snake@GOTPCREL(%rip), %rax + movl -16(%rbp), %edx + movl (%rax,%rdx,4), %eax + leal 1(%rax), %ecx + movq snake@GOTPCREL(%rip), %rax + movl -16(%rbp), %edx + movl %ecx, (%rax,%rdx,4) +.L21: + addl $1, -16(%rbp) +.L20: + cmpl $2399, -16(%rbp) + jbe .L22 + call nib_poll_kbd + movl %eax, -8(%rbp) + cmpl $119, -8(%rbp) + jne .L23 + movq snakeDirY@GOTPCREL(%rip), %rax + movl (%rax), %eax + cmpl $1, %eax + je .L23 + movq snakeDirX@GOTPCREL(%rip), %rax + movl $0, (%rax) + movq snakeDirY@GOTPCREL(%rip), %rax + movl $-1, (%rax) +.L23: + cmpl $115, -8(%rbp) + jne .L24 + movq snakeDirY@GOTPCREL(%rip), %rax + movl (%rax), %eax + cmpl $-1, %eax + je .L24 + movq snakeDirX@GOTPCREL(%rip), %rax + movl $0, (%rax) + movq snakeDirY@GOTPCREL(%rip), %rax + movl $1, (%rax) +.L24: + cmpl $97, -8(%rbp) + jne .L25 + movq snakeDirX@GOTPCREL(%rip), %rax + movl (%rax), %eax + cmpl $1, %eax + je .L25 + movq snakeDirX@GOTPCREL(%rip), %rax + movl $-1, (%rax) + movq snakeDirY@GOTPCREL(%rip), %rax + movl $0, (%rax) +.L25: + cmpl $100, -8(%rbp) + jne .L26 + movq snakeDirX@GOTPCREL(%rip), %rax + movl (%rax), %eax + cmpl $-1, %eax + je .L26 + movq snakeDirX@GOTPCREL(%rip), %rax + movl $1, (%rax) + movq snakeDirY@GOTPCREL(%rip), %rax + movl $0, (%rax) +.L26: + movq snakeX@GOTPCREL(%rip), %rax + movl (%rax), %edx + movq snakeDirX@GOTPCREL(%rip), %rax + movl (%rax), %eax + addl %edx, %eax + leal 60(%rax), %ecx + movl $-2004318071, %edx + movl %ecx, %eax + mull %edx + movl %edx, %eax + shrl $5, %eax + movl %eax, %edx + leal 0(,%rdx,4), %eax + movl %eax, %edx + movl %edx, %eax + sall $4, %eax + subl %edx, %eax + subl %eax, %ecx + movl %ecx, %eax + movq snakeX@GOTPCREL(%rip), %rdx + movl %eax, (%rdx) + movq snakeY@GOTPCREL(%rip), %rax + movl (%rax), %edx + movq snakeDirY@GOTPCREL(%rip), %rax + movl (%rax), %eax + addl %edx, %eax + leal 40(%rax), %ecx + movl $-858993459, %edx + movl %ecx, %eax + mull %edx + shrl $5, %edx + movl %edx, %eax + sall $2, %eax + addl %edx, %eax + sall $3, %eax + subl %eax, %ecx + movl %ecx, %edx + movq snakeY@GOTPCREL(%rip), %rax + movl %edx, (%rax) + movq snakeY@GOTPCREL(%rip), %rax + movl (%rax), %eax + sall $2, %eax + movl %eax, %edx + sall $4, %edx + subl %eax, %edx + movq snakeX@GOTPCREL(%rip), %rax + movl (%rax), %eax + addl %eax, %edx + movq snake@GOTPCREL(%rip), %rax + movl %edx, %edx + movl (%rax,%rdx,4), %eax + movl %eax, -4(%rbp) + movl -4(%rbp), %edx + movq snakeLength@GOTPCREL(%rip), %rax + movl (%rax), %eax + cmpl %eax, %edx + jae .L27 + cmpl $0, -4(%rbp) + js .L27 + movl startApples(%rip), %eax + movl %eax, %edx + movl startLength(%rip), %eax + movl %edx, %esi + movl %eax, %edi + call start_game +.L27: + cmpl $0, -4(%rbp) + jns .L28 + movl $0, %eax + call spawnApple + movq snakeLength@GOTPCREL(%rip), %rax + movl (%rax), %eax + leal 1(%rax), %edx + movq snakeLength@GOTPCREL(%rip), %rax + movl %edx, (%rax) +.L28: + movq snakeY@GOTPCREL(%rip), %rax + movl (%rax), %eax + sall $2, %eax + movl %eax, %edx + sall $4, %edx + subl %eax, %edx + movq snakeX@GOTPCREL(%rip), %rax + movl (%rax), %eax + addl %eax, %edx + movq snake@GOTPCREL(%rip), %rax + movl %edx, %edx + movl $0, (%rax,%rdx,4) + leave + .cfi_def_cfa 7, 8 + ret + .cfi_endproc +.LFE6: + .size tick, .-tick + .globl draw + .type draw, @function +draw: +.LFB7: + .cfi_startproc + pushq %rbp + .cfi_def_cfa_offset 16 + .cfi_offset 6, -16 + movq %rsp, %rbp + .cfi_def_cfa_register 6 + subq $64, %rsp + movq %fs:40, %rax + movq %rax, -8(%rbp) + xorl %eax, %eax + movabsq $23438616898455886, %rax + movq %rax, -16(%rbp) + movl $-1, -52(%rbp) + jmp .L30 +.L43: + movl $-1, -48(%rbp) + jmp .L31 +.L42: + cmpl $-1, -48(%rbp) + je .L32 + cmpl $-1, -52(%rbp) + je .L32 + cmpl $60, -48(%rbp) + je .L32 + cmpl $40, -52(%rbp) + jne .L33 +.L32: + cmpl $-1, -48(%rbp) + je .L34 + cmpl $-1, -52(%rbp) + jne .L35 +.L34: + movl -48(%rbp), %eax + addl $1, %eax + movl %eax, -24(%rbp) + movl -52(%rbp), %eax + addl $1, %eax + movl %eax, -20(%rbp) + movl -20(%rbp), %ecx + movl -24(%rbp), %eax + movl $35, %edx + movl %ecx, %esi + movl %eax, %edi + call nib_put_scr + nop + jmp .L37 +.L35: + movl -48(%rbp), %eax + addl $1, %eax + movl %eax, -32(%rbp) + movl -52(%rbp), %eax + addl $1, %eax + movl %eax, -28(%rbp) + movl -28(%rbp), %ecx + movl -32(%rbp), %eax + movl $35, %edx + movl %ecx, %esi + movl %eax, %edi + call nib_put_scr + jmp .L37 +.L33: + movl -52(%rbp), %eax + sall $2, %eax + movl %eax, %edx + sall $4, %edx + subl %eax, %edx + movl -48(%rbp), %eax + addl %eax, %edx + movq snake@GOTPCREL(%rip), %rax + movslq %edx, %rdx + movl (%rax,%rdx,4), %eax + movl %eax, -44(%rbp) + movl -48(%rbp), %eax + addl $1, %eax + movl %eax, -40(%rbp) + movl -52(%rbp), %eax + addl $1, %eax + movl %eax, -36(%rbp) + cmpl $0, -44(%rbp) + js .L38 + movl -44(%rbp), %edx + movq snakeLength@GOTPCREL(%rip), %rax + movl (%rax), %eax + cmpl %eax, %edx + jae .L38 + movl -48(%rbp), %edx + movq snakeX@GOTPCREL(%rip), %rax + movl (%rax), %eax + cmpl %eax, %edx + jne .L39 + movl -52(%rbp), %edx + movq snakeY@GOTPCREL(%rip), %rax + movl (%rax), %eax + cmpl %eax, %edx + jne .L39 + movl -36(%rbp), %ecx + movl -40(%rbp), %eax + movl $64, %edx + movl %ecx, %esi + movl %eax, %edi + call nib_put_scr + jmp .L37 +.L39: + movl -44(%rbp), %eax + leal -1(%rax), %ecx + movl $-1840700269, %edx + movl %ecx, %eax + imull %edx + leal (%rdx,%rcx), %eax + sarl $2, %eax + movl %eax, %edx + movl %ecx, %eax + sarl $31, %eax + subl %eax, %edx + movl %edx, %eax + movl %eax, %edx + sall $3, %edx + subl %eax, %edx + movl %ecx, %eax + subl %edx, %eax + cltq + movzbl -16(%rbp,%rax), %eax + movsbl %al, %edx + movl -36(%rbp), %ecx + movl -40(%rbp), %eax + movl %ecx, %esi + movl %eax, %edi + call nib_put_scr + jmp .L37 +.L38: + cmpl $0, -44(%rbp) + jns .L41 + movl -36(%rbp), %ecx + movl -40(%rbp), %eax + movl $111, %edx + movl %ecx, %esi + movl %eax, %edi + call nib_put_scr + jmp .L37 +.L41: + movl -36(%rbp), %ecx + movl -40(%rbp), %eax + movl $32, %edx + movl %ecx, %esi + movl %eax, %edi + call nib_put_scr +.L37: + addl $1, -48(%rbp) +.L31: + cmpl $60, -48(%rbp) + jle .L42 + addl $1, -52(%rbp) +.L30: + cmpl $40, -52(%rbp) + jle .L43 + movq -8(%rbp), %rax + xorq %fs:40, %rax + je .L44 + call __stack_chk_fail@PLT +.L44: + leave + .cfi_def_cfa 7, 8 + ret + .cfi_endproc +.LFE7: + .size draw, .-draw + .ident "GCC: (GNU) 4.9.2" + .section .note.GNU-stack,"",@progbits diff --git a/cnibbles.c b/cnibbles.c new file mode 100644 index 0000000..d336e46 --- /dev/null +++ b/cnibbles.c @@ -0,0 +1,178 @@ +#include +#include +#include "helpers.c" + +#define WIDTH 60 +#define HEIGHT 40 +#define DEBUG false + +unsigned int startLength = 0; +unsigned int startApples = 0; + +unsigned int currentTick; +int snake[WIDTH*HEIGHT]; +unsigned int snakeLength; +unsigned int snakeX; +unsigned int snakeY; +int snakeDirX; +int snakeDirY; +unsigned int numApples; + +void spawnApple(); +void tick(); +void draw(); + +void start_game(int len, int n_apples) +{ + if (startLength == 0) + startLength = len; + if (startApples == 0) + startApples = n_apples; + + // Initialize variables + currentTick = 0; + snakeLength = len; + numApples = n_apples; + + nib_init(); + + //printf("Started with worm length %i and %i apples!\n", snakeLength, numApples); + + // Initialize the snake array + // Set every cell to a time value greater than the snake length + for (unsigned int i = 0; i < WIDTH*HEIGHT; ++i) { + snake[i] = snakeLength; + } + + // Place the snake head in the middle + snakeX = WIDTH / 2; + snakeY = HEIGHT / 2; + snakeDirX = 0; + snakeDirY = -1; + + // Place the initial snake segments, downwards or something + for (unsigned int i = 0; i < snakeLength; ++i) { + unsigned int x = snakeX % WIDTH; + unsigned int y = (snakeY + i) % HEIGHT; + snake[x + y*WIDTH] = i; + } + + // Place apples + srand(time(0)); + for (unsigned int i = 0; i < numApples; ++i) { + spawnApple(); + } + + while (true) { + tick(); + draw(); + } +} + +void spawnApple() +{ + unsigned int x = rand() % WIDTH; + unsigned int y = rand() % HEIGHT; + while (snake[x + y*WIDTH] < snakeLength) { + x = rand() % WIDTH; + y = rand() % HEIGHT; + } + //printf("Placing apple at (%i,%i)\n", x, y); + snake[x + y*WIDTH] = -1; +} + +void tick() +{ + currentTick++; + // Increment cell times + for (unsigned int i = 0; i < WIDTH*HEIGHT; ++i) { + int val = snake[i]; + + if (val < 0) { + // Apple lifetime + //snake[i]--; + } else if (val >= 0 && val <= snakeLength) { + // Other cells + snake[i]++; + } + } + + int key = nib_poll_kbd(); + if (key == 'w' && snakeDirY != 1) { + snakeDirX = 0; + snakeDirY = -1; + } + if (key == 's' && snakeDirY != -1) { + snakeDirX = 0; + snakeDirY = 1; + } + if (key == 'a' && snakeDirX != 1) { + snakeDirX = -1; + snakeDirY = 0; + } + if (key == 'd' && snakeDirX != -1) { + snakeDirX = 1; + snakeDirY = 0; + } + + // Move snake + snakeX = (snakeX + snakeDirX + WIDTH) % WIDTH; + snakeY = (snakeY + snakeDirY + HEIGHT) % HEIGHT; + // On collision with self + int val = snake[snakeX + snakeY*WIDTH]; + if (val < snakeLength && val >= 0) { + //nib_end(); + start_game(startLength, startApples); + } + // ON collision with apple + if (val < 0) { + // Spawn a new apple somewhere + spawnApple(); + // Increase our length! + snakeLength++; + } + snake[snakeX + snakeY*WIDTH] = 0; +} + +void draw() +{ + char body[] = "NIBBLES"; + + for (int y = -1; y <= HEIGHT; ++y) { + for (int x = -1; x <= WIDTH; ++x) { + + if (x == -1 || y == -1 || x == WIDTH || y == HEIGHT) { + if (x == -1 || y == -1) { + unsigned int screenX = x + 1; + unsigned int screenY = y + 1; + nib_put_scr(screenX, screenY, '#'); + } else { + unsigned int screenX = x + 1; + unsigned int screenY = y + 1; + nib_put_scr(screenX, screenY, '#'); + } + } else { + int snakeVal = snake[x + y*WIDTH]; + unsigned int screenX = x + 1; + unsigned int screenY = y + 1; + + if (DEBUG) { + nib_put_scr(screenX, screenY, '0' + snakeVal); + continue; + } + + if (snakeVal >= 0 && snakeVal < snakeLength) { + if (x == snakeX && y == snakeY) { + nib_put_scr(screenX, screenY, '@'); + } else { + nib_put_scr(screenX, screenY, body[(snakeVal - 1) % 7]); + } + } else if (snakeVal < 0) { + nib_put_scr(screenX, screenY, 'o'); + } else { + nib_put_scr(screenX, screenY, ' '); + } + } + } + } +} diff --git a/helpers.c b/helpers.c new file mode 100644 index 0000000..f050e8a --- /dev/null +++ b/helpers.c @@ -0,0 +1,48 @@ +/********************************************************************* + * + * Copyright (C) 2003, Blekinge Institute of Technology + * + * Filename: helpers.c + * Author: Simon Kagstrom + * Description: Library with helpers for the nibbles game + * + * $Id: helpers.c 4937 2005-10-06 12:50:50Z ska $ + * + ********************************************************************/ +#include +#include +#include +#include + +static WINDOW *p_screen; + +int nib_poll_kbd(void) +{ + int key = getch(); + + return key; +} + +void nib_put_scr(int x, int y, int ch) +{ + mvprintw(y, x, "%c", ch); + wrefresh(p_screen); +} + +void nib_init(void) +{ + + srand(time(0)); /* Init randomiser */ + p_screen = initscr(); /* Create the window */ + start_color(); /* We use color (well...) */ + curs_set(0); /* Make cursor invisible */ + noecho(); /* Don't output chars on screen when written */ + keypad(p_screen, TRUE); /* Give p_screen keyboard focus */ + nodelay(p_screen, TRUE); /* Make getch nonblocking */ +} + +void nib_end(void) +{ + endwin(); + exit(0); +} diff --git a/main.c b/main.c new file mode 100644 index 0000000..9a1e7b9 --- /dev/null +++ b/main.c @@ -0,0 +1,33 @@ +/********************************************************************* + * + * Copyright (C) 2003, Blekinge Institute of Technology + * + * Filename: main.c + * Author: Simon Kagstrom + * Description: main function for nibbles game. + * + * $Id: main.c 1369 2005-01-20 20:57:54Z ska $ + * + ********************************************************************/ +#include /* printf */ +#include /* atoi */ + +extern void start_game(int len, int n_apples); + +int main(int argc, char *argv[]) +{ + int len, apples; + + if (argc < 3) + { + printf("Usage: %s LEN APPLES\n", argv[0]); + return 1; + } + + len = atoi(argv[1]); + apples = atoi(argv[2]); + + start_game(len, apples); + + return 0; +} diff --git a/main.o b/main.o new file mode 100644 index 0000000000000000000000000000000000000000..2db64724e642118e907e6f7551834e023bb26676 GIT binary patch literal 3964 zcma)9TWlOx89rxb*1PsPUat+rxfD$*mj;B#-85Kf;DUh){Xqr4i=)&YZJ5 z4j}lYbH4v}{{P(P%=P)j6H-cHND5o@Bq7F#L*{o(|pKJT&;IR8p+g+SL z<<8{ui}Pm&#I40~XY>7!wyxYecjJSlFQ56+=H1kX_qMjSUc7Cg(akH)=400NJxg0t zw>B9x|5d5Xn|FraVdlS%Z{8i;T6dK4*{$`|jrSD0d@;Xd9CN?86@0Y(+{MC$TmHS< zH}{U;ei2O_h7*pwfm-fCwN5!kmXjQUXvtKGU?o2!I7v?_`yN!v#BPMLokX<}3M-X> z4v;)Xa1wt~ko+98IU5vY-$j7qyo5SIP2a~7vchcfsaR zGKWyjLL)Lyqq+btbKWpMm=YL2UhlWPe_RyZ8b33zgcqammi*)*Ns1QK2DP+t*yD*9w`-~v;dGd)}_R!(JFh(uXq#`T;A_UKAb`%#*5FafRX(mtTOv5@%6M`SH*W)apQUc_usU z)?~F&s&!U^$znBZi?~LJx?gR0JPe{8u2h=`yb4b@_*%6HUiBiOYC9`ae|*BR?B9#? zj&a8++&TB4_n3FUov1&`%5Rk_N2^nZrre3L zJ8`=0PGEpXOSzmov6^3)N8Jwn(&dS@Rx=DrVY3B$3*!-f*sMl<!hg?d#K3K3H%RW4%&{Z?2g`}IJ#pktx1S`S6L`g{;xT?-fw7u3nQxx?;$^!l?= zr?C{D;Cg`M^Unx*EhYC1I?l^jmSfOyZ;;gbA0L$Bf8! zux)ihYx!L`%-o*&)y#V{znnu9Y-zN;!~me~?(*7K>!Dv19>yJE#c*M;5ejd`4}IYk z+il^sniS}n^K!zY-Rm@J)yqNcDy%^*QmF~(tZ9crVdK!0R}R9$TB#6LI*rR-aU=3x z35uO^q1sq&B8}qxVzCvh$E~$yDK7dgzfs0gt87u5f7jHijle`iXN6a4*6RUQ!E0cZ zJxn-O8LJ*e2`Yuv7FWwFx0>ko|4o=+b@7@8{7&M66a4&q3WambLK&_&>k&)-xuM- zH-e!b?+}6?BhEt-g>%CGe+5Owi!MBIN8133OuTE53{S(aQC^BE47&k+Jn#F+I|d{3 z4xpI4FM~I2z>24l|DR+u85_T(hNtN%O!$KKAsE}Y!N>F7!w2t4=$IE>=;r+qc+&=~ zcn$GfGMbF-4ao6$$1~B{WjwImcs~bk+JF^5MLeEyL&o+F6!CaxWAXTKF!Skd=q|gGB!SD$m?w-UV~r!SaZB2u6cYMwb;Di5z!q7=Ll2LB?kv!)Fgw}u<@L9 z{$W~(x1rn%{*x%o%k^Q-c)UC|$#c*dGVzRTFs^sR-?xmOXm>{&Y3*$pXg8xa_U)5r zcTcsk^Q893-ZoQ=#}m~fTMYIDaJJg{J(aC?Zd~T9_Q+N{CoXfwdSnZ{<6>lsF}3G< zs{6+izvNK4K3EwSO!OiDzs8Q^C8v9|Pbw$H8V@AmSy; zmmu*1ad&iAODq*vM`C|-)`^^5A|J03`)?l+_ZH`X`bmvb8jor`u90&=zh#Y=G?q0s zG=5FvO^x5v_?E_>5V6(X)$;E&{)LG1b63m%&@wkY{YP*ZXx~YMyiX(l&M2#&DBv7r z^z)*|wnl_eemoWQM<|7GRmi_9>L1jY)A$9A(?o1JehVcIG|x5tNkkLZ*Rl(=pkE>4 Gviui;#M3$e literal 0 HcmV?d00001 diff --git a/nibbles.S b/nibbles.S new file mode 100644 index 0000000..9213b40 --- /dev/null +++ b/nibbles.S @@ -0,0 +1,369 @@ +#define WIDTH 60 +#define HEIGHT 40 + +.bss +# Array of longs representing the game field +.align 4 +world: .space WIDTH*HEIGHT*4 + +.data +# Current length of the snake +snakeLength: .long 0 +# Snake position +snakePosX: .long WIDTH / 2 +snakePosY: .long HEIGHT / 2 +# Snake direction +snakeDirX: .long 1 +snakeDirY: .long 0 +# Number of apples +numApples: .long 0 +# Optional score-keeping +score: .long 0 +# Utility strings +snibbles: .ascii "NIBBLES" +sgameover: .string " Game over! Score: %i " +sgameover_end: +string1: .string "Started with snake length %i and %i apples!\n" +string2: .string "Snake position: (%i, %i)\n" +stringi: .string "%i\n" +stringtest: .string "> %i %i %c\n" + +.text +.global start_game +start_game: + # snakeLength = len + movl 4(%esp), %eax + movl %eax, snakeLength + # numApples = n_apples + movl 8(%esp), %eax + movl %eax, numApples + + pushl %ebx + pushl %edi + + # Call nib_init + call nib_init + # Seed randomness + pushl $0 + call time + addl $4, %esp + pushl %eax + call srand + addl $4, %esp + + # Print our arguments + #pushl numApples + #pushl snakeLength + #pushl $string1 + #call printf + #addl $4*3, %esp + + # Print worm position + #pushl snakePosY + #pushl snakePosX + #pushl $string2 + #call printf + #addl $4*3, %esp + + # Initialize the snake array + # Set every cell to a time value greater than the snake length + movl $world, %edi + movl snakeLength, %eax + movl $WIDTH*HEIGHT, %ebx + xorl %ecx, %ecx +1: + movl %eax, (%edi, %ecx, 4) + incl %ecx + cmpl %ebx, %ecx + jl 1b + + # Spawn initial apples + movl numApples, %ecx +1: + pushl %ecx + call spawnApple + popl %ecx + loop 1b + + # Loop forever +loop: + # Sleep for 150 ms + pushl $500*1000 + call usleep + addl $4, %esp + jmp tick + + popl %edi + popl %ebx + ret + +# Update stuff +tick: + movl $world, %edi + + # Increment cell times + movl snakeLength, %ebx + xorl %ecx, %ecx +1: + movl (%edi, %ecx, 4), %eax + # If the value is negative it's an apple we don't want to disappear + test %eax, %eax + js 2f + # No need to increment if it's already greater than snakeLength + cmpl %ebx, %eax + jg 2f + # Increment the cell value + incl %eax + movl %eax, (%edi, %ecx, 4) +2: incl %ecx # Loop increment + cmpl $WIDTH*HEIGHT, %ecx + jne 1b + + # Input + call nib_poll_kbd + # Down + movl $258, %ebx + cmpl %eax, %ebx + jne 1f + movl $0, snakeDirX + movl $1, snakeDirY +1: # Up + movl $259, %ebx + cmpl %eax, %ebx + jne 1f + movl $0, snakeDirX + movl $-1, snakeDirY +1: # Left + movl $260, %ebx + cmpl %eax, %ebx + jne 1f + movl $-1, snakeDirX + movl $0, snakeDirY +1: # Right + movl $261, %ebx + cmpl %eax, %ebx + jne 1f + movl $1, snakeDirX + movl $0, snakeDirY +1: + + # Move snake + # snakePosX = (snakePosX + snakeDirY + WIDTH) % WIDTH + movl snakePosX, %eax + movl snakeDirX, %ebx + addl %ebx, %eax + addl $WIDTH, %eax # For modulo wrap-around + xorl %edx, %edx + movl $WIDTH, %ecx + divl %ecx + mov %edx, snakePosX + # snakePosY = (snakePosY + snakeDirY + HEIGHT) % HEIGHT + movl snakePosY, %eax + movl snakeDirY, %ebx + addl %ebx, %eax + addl $HEIGHT, %eax # For modulo wrap-around + xorl %edx, %edx + movl $HEIGHT, %ecx + divl %ecx + mov %edx, snakePosY + + # Get value at head position + movl snakePosY, %eax + movl $WIDTH, %edx + mull %edx + addl snakePosX, %eax + movl (%edi, %eax, 4), %edx + + # Collision with apple if negative + test %edx, %edx + js 1f + # No need to increment if it's already greater than snakeLength + movl snakeLength, %ebx + cmpl %ebx, %edx + jg 2f + # End the game when the snake collides with itself + jmp gameOver +1: # Spawn a new apple + pushl %edi + pushl %eax + call spawnApple + popl %eax + popl %edi + # Extend the snake! + incl snakeLength +2: + + # Set time value to 0 at snake head position + # i = x + y * WIDTH + # %edi = %ebx + %ecx * $WIDTH + movl $0, (%edi, %eax, 4) + + jmp draw + #jmp debug_draw + +# Draw stuff +draw: + # Loop Y + movl $HEIGHT, %ecx +1: + # Loop X + movl $WIDTH, %ebx +2: + # Save loop registers + pushl %ecx + pushl %ebx + subl $1, %ecx + subl $1, %ebx + + # Call nib_put_scr + + # i = x + y * WIDTH + # %eax = %ebx + %ecx * $WIDTH + movl %ecx, %eax + movl $WIDTH, %edx + mull %edx + addl %ebx, %eax + # Fetch the value of the cell + movl $world, %edi + movl (%edi, %eax, 4), %eax + + # Compare with the snake length + cmpl snakeLength, %eax + # If the value is negative, it's an apple + test %eax, %eax + js 4f + # If it's greater or equal to snakeLength, it's empty + cmpl snakeLength, %eax + jge 3f + # Else, it's part of the snake + pushl $'@' + jmp 5f +3: pushl $' ' + jmp 5f +4: pushl $'o' +5: + + movl %ecx, %eax # Y + pushl %eax + + movl %ebx, %eax # X + pushl %eax + + call nib_put_scr + addl $4*3, %esp + + # Restore loop registers + popl %ebx + popl %ecx + + decl %ebx # Decrement X + jnz 2b # End of X loop + loop 1b # End of Y loop + + jmp loop + +# Debug drawing +debug_draw: + # Loop Y + movl $HEIGHT, %ecx +1: + # Loop X + movl $WIDTH, %ebx +2: + # Save loop registers + pushl %ecx + pushl %ebx + subl $1, %ecx + subl $1, %ebx + + # Call nib_put_scr + + # i = x + y * WIDTH + # %edi = %ebx + %ecx * $WIDTH + movl %ecx, %eax + movl $WIDTH, %edx + mull %edx + addl %ebx, %eax + # Fetch the value of the cell + movl $world, %edi + movl (%edi, %eax, 4), %eax + pushl %eax + + movl %ecx, %eax # Y + pushl %eax + + movl %ebx, %eax # X + pushl %eax + + call nib_put_scr + addl $4*3, %esp + + # Restore loop registers + popl %ebx + popl %ecx + + decl %ebx # Decrement X + jnz 2b # End of X loop + loop 1b # End of Y loop + + jmp loop + +gameOver: + # Calculate string length + movl $sgameover_end, %eax + subl $sgameover, %eax + subl $1, %eax # Discount null terminator + + # Calculate X-pos + movl $2, %ebx + xorl %edx, %edx + divl %ebx + negl %eax + addl $WIDTH/2, %eax + + # Print game over message + pushl snakeLength + pushl $sgameover + pushl %eax # X + pushl $HEIGHT/2 # Y + call mvprintw + add $4*3, %esp + call refresh + + pushl $3000*1000 + call usleep + addl $4, %esp + call nib_end + +spawnApple: + pushl %ebx + + # %ecx = rand() % HEIGHT + call rand + xorl %edx, %edx + movl $HEIGHT, %ebx + divl %ebx + movl %edx, %ecx + # %ebx = rand() % WIDTH + pushl %ecx + call rand + xorl %edx, %edx + movl $WIDTH, %ebx + divl %ebx + movl %edx, %ebx + popl %ecx + + # i = x + y * WIDTH + # %eax = %ebx + %ecx * $WIDTH + movl %ecx, %eax + movl $WIDTH, %edx + mull %edx + addl %ebx, %eax + + # Set the cell negative to represent an apple + movl $world, %ecx + movl $-1, %edx + movl %edx, (%ecx, %eax, 4) + + popl %ebx + ret diff --git a/start.S b/start.S new file mode 100644 index 0000000..252d351 --- /dev/null +++ b/start.S @@ -0,0 +1,12 @@ +.text +.global _start +_start: + # n_apples + pushl $10 + # len + pushl $3 + call start_game + addl $4*2, %esp + + movl $0, %eax + ret diff --git a/test.c b/test.c new file mode 100644 index 0000000..909c7e4 --- /dev/null +++ b/test.c @@ -0,0 +1,9 @@ +int main(int argc, char* argv[]) +{ + for (int x = 0; x < 10; ++x) { + for (int y = 0; y < 20; ++y) { + nib_put_scr(x, y, '@'); + } + } + return 0; +} diff --git a/test.s b/test.s new file mode 100644 index 0000000..57ffda4 --- /dev/null +++ b/test.s @@ -0,0 +1,85 @@ + .file "test.c" + .section .text.unlikely,"ax",@progbits +.LCOLDB0: + .section .text.startup,"ax",@progbits +.LHOTB0: + .p2align 4,,15 + .globl main + .type main, @function +main: +.LFB0: + .cfi_startproc + leal 4(%esp), %ecx + .cfi_def_cfa 1, 0 + andl $-16, %esp + pushl -4(%ecx) + pushl %ebp + .cfi_escape 0x10,0x5,0x2,0x75,0 + movl %esp, %ebp + pushl %edi + pushl %esi + pushl %ebx + pushl %ecx + .cfi_escape 0xf,0x3,0x75,0x70,0x6 + .cfi_escape 0x10,0x7,0x2,0x75,0x7c + .cfi_escape 0x10,0x6,0x2,0x75,0x78 + .cfi_escape 0x10,0x3,0x2,0x75,0x74 + xorl %edi, %edi + call __x86.get_pc_thunk.bx + addl $_GLOBAL_OFFSET_TABLE_, %ebx + subl $8, %esp + .p2align 4,,10 + .p2align 3 +.L2: + xorl %esi, %esi + .p2align 4,,10 + .p2align 3 +.L3: + subl $4, %esp + pushl $64 + pushl %esi + addl $1, %esi + pushl %edi + call nib_put_scr@PLT + addl $16, %esp + cmpl $20, %esi + jne .L3 + addl $1, %edi + cmpl $10, %edi + jne .L2 + leal -16(%ebp), %esp + xorl %eax, %eax + popl %ecx + .cfi_restore 1 + .cfi_def_cfa 1, 0 + popl %ebx + .cfi_restore 3 + popl %esi + .cfi_restore 6 + popl %edi + .cfi_restore 7 + popl %ebp + .cfi_restore 5 + leal -4(%ecx), %esp + .cfi_def_cfa 4, 4 + ret + .cfi_endproc +.LFE0: + .size main, .-main + .section .text.unlikely +.LCOLDE0: + .section .text.startup +.LHOTE0: + .section .text.__x86.get_pc_thunk.bx,"axG",@progbits,__x86.get_pc_thunk.bx,comdat + .globl __x86.get_pc_thunk.bx + .hidden __x86.get_pc_thunk.bx + .type __x86.get_pc_thunk.bx, @function +__x86.get_pc_thunk.bx: +.LFB1: + .cfi_startproc + movl (%esp), %ebx + ret + .cfi_endproc +.LFE1: + .ident "GCC: (GNU) 4.9.2" + .section .note.GNU-stack,"",@progbits diff --git a/workaround.S b/workaround.S new file mode 100644 index 0000000..a3197d4 --- /dev/null +++ b/workaround.S @@ -0,0 +1,9 @@ +.data + +.globl __progname +__progname: + .int 0 + +.globl environ +environ: + .byte 0