Compare commits

..

No commits in common. 'opt' and 'master' have entirely different histories.
opt ... master

  1. 126
      brainfuck.asm

@ -31,8 +31,8 @@ bf_tape: resb TAPE_SIZE
section .text: section .text:
; Podczas interpretacji programu znaczenia rejestrów są następujące: ; Podczas interpretacji programu znaczenia rejestrów są następujące:
; - rdi jest wskaźnikiem programu ; - rsi jest wskaźnikiem programu
; - rsi jest wskaźnikiem na aktualne pole na taśmie ; - rbx jest wskaźnikiem na aktualne pole na taśmie
; Tablica 8-bajtowych kawałków kodu, w której na miejscu 8*i znajduje się kod zakończony ; Tablica 8-bajtowych kawałków kodu, w której na miejscu 8*i znajduje się kod zakończony
; instrukcją powrotu, który należy wykonać dla znaku o kodzie ascii równym i. Operacje, ; instrukcją powrotu, który należy wykonać dla znaku o kodzie ascii równym i. Operacje,
@ -43,78 +43,84 @@ bf_instructions:
xor rdi, rdi xor rdi, rdi
call exit call exit
align 8 align 8
times 8*('+'-1) hlt times 8*('+'-1) ret
bf_increment: ; '+' ascii 43 bf_increment: ; '+' ascii 43
inc byte [rdi] inc byte [rsi]
inc rsi inc rbx
jmp rbx ret
align 8 align 8
bf_in_stub: ; ',' ascii 44 bf_in_stub: ; ',' ascii 44
jmp bf_in jmp bf_in
align 8 align 8
bf_decr: ; '-' ascii 45 bf_decr: ; '-' ascii 45
dec byte [rdi] dec byte [rsi]
inc rsi inc rbx
jmp rbx ret
align 8 align 8
bf_out_stub: ; '.' ascii 46 bf_out_stub: ; '.' ascii 46
jmp bf_out jmp bf_out
ret
align 8 align 8
times 8*('<'-'.'-1) hlt times 8*('<'-'.'-1) ret
bf_left: ; '<' ascii 60 bf_left: ; '<' ascii 60
dec rdi dec rsi
inc rsi inc rbx
jmp rbx ret
align 8 align 8
times 8*('>'-'<'-1) hlt times 8*('>'-'<'-1) ret
bf_right: ; '>' ascii 62 bf_right: ; '>' ascii 62
inc rdi
inc rsi inc rsi
jmp rbx inc rbx
ret
align 8 align 8
times 8*('['-'>'-1) hlt times 8*('['-'>'-1) ret
bf_forward_stub: ; '[' ascii 91
bf_forward: ; '[' ascii 91 jmp bf_forward
; jest 16 bajtów miejsca align 8
cmp byte [rdi], 0 times 8*(']'-'['-1) ret
jne .dont_jump bf_backward_stub: ; ']' ascii 93
mov rsi, [8*rsi + r14] jmp bf_backward
.dont_jump:
inc rsi
jmp rbx
align 8 align 8
bf_backward: ; ']' ascii 93 bf_forward:
; więcej niż 8 bajtów, ale jest miejsce cmp byte [rsi], 0
cmp byte [rdi], 0 jne bf_forward_end
je .dont_jump jmp bf_jump
mov rsi, [8*rsi + r14] bf_forward_end:
.dont_jump: inc rbx
inc rsi ret
jmp rbx
bf_backward:
cmp byte [rsi], 0
je bf_backward_end
jmp bf_jump
bf_backward_end:
inc rbx
ret
bf_jump:
sub rbx, bf_program
mov rbx, [8*rbx + bf_jumps]
inc rbx
ret
bf_out: bf_out:
push rdi movzx rdi, byte [rsi]
push rsi push rsi
movzx rdi, byte [rdi]
call putchar call putchar
xor rdi, rdi xor rdi, rdi
call fflush call fflush
pop rsi pop rsi
pop rdi inc rbx
inc rsi ret
jmp rbx
bf_in: bf_in:
push rdi
push rsi push rsi
call getchar call getchar
pop rsi pop rsi
pop rdi mov byte [rsi], al
mov byte [rdi], al inc rbx
inc rsi ret
jmp rbx
main: main:
@ -125,41 +131,35 @@ call gets
; Buduję tablicę skoków dla ']'. Jeśli i-ty znak programu to nawias, to na 8*i-tym miejscu w tablicy ; Buduję tablicę skoków dla ']'. Jeśli i-ty znak programu to nawias, to na 8*i-tym miejscu w tablicy
; skoków znajdzie się adres odpowiadającego mu nawiasu. ; skoków znajdzie się adres odpowiadającego mu nawiasu.
lea rsi, [bf_program] lea rbx, [bf_program]
lea r12, [bf_jumps] lea r12, [bf_jumps]
_jump_loop: _jump_loop:
cmp byte [rsi], '[' cmp byte [rbx], '['
jne .else jne .else
push r12 push r12
push rsi push rbx
jmp .end jmp .end
.else: .else:
cmp byte [rsi], ']' cmp byte [rbx], ']'
jne .end jne .end
pop rax pop rax
mov qword [r12], rax mov qword [r12], rax
pop rax pop rax
mov qword [rax], rsi mov qword [rax], rbx
.end: .end:
inc rsi inc rbx
add r12, 8 add r12, 8
cmp byte [rsi], 0 cmp byte [rbx], 0
jnz _jump_loop jnz _jump_loop
lea rsi, [bf_program] lea rbx, [bf_program]
lea rdi, [bf_tape] lea rsi, [bf_tape]
lea rbx, [_program_loop] ; stała
lea r13, [bf_program]
shl r13, 3
lea r14, [bf_jumps]
sub r14, r13 ; stała do zamiany adresu programu na adres w bf_jumps
_program_loop: _program_loop:
movzx rax, byte [rsi] movzx rax, byte [rbx]
lea rax, [bf_instructions + 8*rax] lea rax, [bf_instructions + 8*rax]
jmp rax call rax
jmp _program_loop
xor rdi, rdi xor rdi, rdi
call exit call exit

Loading…
Cancel
Save