section .text
global _start
_start:
xor r8, r8
xor r9, r9
xor r10, r10
_do_while:
_getchar:
cmp r9, r10
jne _getchar_done
_getchar_read_buffer:
xor r9, r9
xor eax, eax
xor edi, edi
mov rsi, in_buf
mov rdx, inbuf_maxlen
syscall
mov r10, rax
_getchar_done:
mov al, [in_buf + r9]
inc r9
_do_while_cont:
cmp al, [req + r8]
jne _reset
_increment:
inc r8
cmp r8, 5
jne _do_while
mov rax, 1
mov rdi, 1
mov rsi, ans
mov rdx, 5
syscall
_end:
mov rax, 60
xor rdi, rdi
syscall
_reset:
xor r8, r8
cmp al, 'd'
jne _do_while
inc r8
jmp _do_while
section .datarodata
inbuf_maxlen equ 1000000
req db "draw!"
ALIGN 8
ans db "bang!"
section .bss
in_buf resb inbuf_maxlen
A little hand-written assembly. Compile with:
nasm -felf64 foobar.s && ld foobar.o -o foobar
Edit: move in_bi
into a register and use xor
.
Edit: used the wrong jump, my code was wrong...
Edit: the previous code had a bug where it would read garbage if the read
syscall did not return a full buffer. This version is more efficient (and correct)...
Edit: make sure to process ddraw!
correctly. Thanks to Anders Kaseorg for the test case.
Edit: re-structure to move getchar
out of a function and to jump less.
Edit: don't xor the high bits of the registers at the suggestion of Cody Gray
Edit: align (thanks to Joshua) and move into .rodata