|
|
|
|
@ -31,8 +31,8 @@ bf_tape: resb TAPE_SIZE |
|
|
|
|
section .text: |
|
|
|
|
|
|
|
|
|
; Podczas interpretacji programu znaczenia rejestrów są następujące: |
|
|
|
|
; - rsi jest wskaźnikiem programu |
|
|
|
|
; - rbx jest wskaźnikiem na aktualne pole na taśmie |
|
|
|
|
; - rdi jest wskaźnikiem programu |
|
|
|
|
; - rsi 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 |
|
|
|
|
; instrukcją powrotu, który należy wykonać dla znaku o kodzie ascii równym i. Operacje, |
|
|
|
|
@ -43,84 +43,78 @@ bf_instructions: |
|
|
|
|
xor rdi, rdi |
|
|
|
|
call exit |
|
|
|
|
align 8 |
|
|
|
|
times 8*('+'-1) ret |
|
|
|
|
times 8*('+'-1) hlt |
|
|
|
|
bf_increment: ; '+' ascii 43 |
|
|
|
|
inc byte [rsi] |
|
|
|
|
inc rbx |
|
|
|
|
ret |
|
|
|
|
inc byte [rdi] |
|
|
|
|
inc rsi |
|
|
|
|
jmp rbx |
|
|
|
|
align 8 |
|
|
|
|
bf_in_stub: ; ',' ascii 44 |
|
|
|
|
jmp bf_in |
|
|
|
|
align 8 |
|
|
|
|
bf_decr: ; '-' ascii 45 |
|
|
|
|
dec byte [rsi] |
|
|
|
|
inc rbx |
|
|
|
|
ret |
|
|
|
|
dec byte [rdi] |
|
|
|
|
inc rsi |
|
|
|
|
jmp rbx |
|
|
|
|
align 8 |
|
|
|
|
bf_out_stub: ; '.' ascii 46 |
|
|
|
|
jmp bf_out |
|
|
|
|
ret |
|
|
|
|
align 8 |
|
|
|
|
times 8*('<'-'.'-1) ret |
|
|
|
|
times 8*('<'-'.'-1) hlt |
|
|
|
|
bf_left: ; '<' ascii 60 |
|
|
|
|
dec rsi |
|
|
|
|
inc rbx |
|
|
|
|
ret |
|
|
|
|
dec rdi |
|
|
|
|
inc rsi |
|
|
|
|
jmp rbx |
|
|
|
|
align 8 |
|
|
|
|
times 8*('>'-'<'-1) ret |
|
|
|
|
times 8*('>'-'<'-1) hlt |
|
|
|
|
bf_right: ; '>' ascii 62 |
|
|
|
|
inc rdi |
|
|
|
|
inc rsi |
|
|
|
|
inc rbx |
|
|
|
|
ret |
|
|
|
|
align 8 |
|
|
|
|
times 8*('['-'>'-1) ret |
|
|
|
|
bf_forward_stub: ; '[' ascii 91 |
|
|
|
|
jmp bf_forward |
|
|
|
|
jmp rbx |
|
|
|
|
align 8 |
|
|
|
|
times 8*(']'-'['-1) ret |
|
|
|
|
bf_backward_stub: ; ']' ascii 93 |
|
|
|
|
jmp bf_backward |
|
|
|
|
times 8*('['-'>'-1) hlt |
|
|
|
|
|
|
|
|
|
bf_forward: ; '[' ascii 91 |
|
|
|
|
; jest 16 bajtów miejsca |
|
|
|
|
cmp byte [rdi], 0 |
|
|
|
|
jne .dont_jump |
|
|
|
|
mov rsi, [8*rsi + r14] |
|
|
|
|
.dont_jump: |
|
|
|
|
inc rsi |
|
|
|
|
jmp rbx |
|
|
|
|
align 8 |
|
|
|
|
|
|
|
|
|
bf_forward: |
|
|
|
|
cmp byte [rsi], 0 |
|
|
|
|
jne bf_forward_end |
|
|
|
|
jmp bf_jump |
|
|
|
|
bf_forward_end: |
|
|
|
|
inc rbx |
|
|
|
|
ret |
|
|
|
|
|
|
|
|
|
bf_backward: |
|
|
|
|
cmp byte [rsi], 0 |
|
|
|
|
je bf_backward_end |
|
|
|
|
jmp bf_jump |
|
|
|
|
bf_backward_end: |
|
|
|
|
inc rbx |
|
|
|
|
ret |
|
|
|
|
bf_backward: ; ']' ascii 93 |
|
|
|
|
; więcej niż 8 bajtów, ale jest miejsce |
|
|
|
|
cmp byte [rdi], 0 |
|
|
|
|
je .dont_jump |
|
|
|
|
mov rsi, [8*rsi + r14] |
|
|
|
|
.dont_jump: |
|
|
|
|
inc rsi |
|
|
|
|
jmp rbx |
|
|
|
|
|
|
|
|
|
bf_jump: |
|
|
|
|
sub rbx, bf_program |
|
|
|
|
mov rbx, [8*rbx + bf_jumps] |
|
|
|
|
inc rbx |
|
|
|
|
ret |
|
|
|
|
|
|
|
|
|
bf_out: |
|
|
|
|
movzx rdi, byte [rsi] |
|
|
|
|
push rdi |
|
|
|
|
push rsi |
|
|
|
|
movzx rdi, byte [rdi] |
|
|
|
|
call putchar |
|
|
|
|
xor rdi, rdi |
|
|
|
|
call fflush |
|
|
|
|
pop rsi |
|
|
|
|
inc rbx |
|
|
|
|
ret |
|
|
|
|
pop rdi |
|
|
|
|
inc rsi |
|
|
|
|
jmp rbx |
|
|
|
|
|
|
|
|
|
bf_in: |
|
|
|
|
push rdi |
|
|
|
|
push rsi |
|
|
|
|
call getchar |
|
|
|
|
pop rsi |
|
|
|
|
mov byte [rsi], al |
|
|
|
|
inc rbx |
|
|
|
|
ret |
|
|
|
|
pop rdi |
|
|
|
|
mov byte [rdi], al |
|
|
|
|
inc rsi |
|
|
|
|
jmp rbx |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
main: |
|
|
|
|
@ -131,35 +125,41 @@ call gets |
|
|
|
|
|
|
|
|
|
; 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. |
|
|
|
|
lea rbx, [bf_program] |
|
|
|
|
lea rsi, [bf_program] |
|
|
|
|
lea r12, [bf_jumps] |
|
|
|
|
_jump_loop: |
|
|
|
|
cmp byte [rbx], '[' |
|
|
|
|
cmp byte [rsi], '[' |
|
|
|
|
jne .else |
|
|
|
|
push r12 |
|
|
|
|
push rbx |
|
|
|
|
push rsi |
|
|
|
|
jmp .end |
|
|
|
|
.else: |
|
|
|
|
cmp byte [rbx], ']' |
|
|
|
|
cmp byte [rsi], ']' |
|
|
|
|
jne .end |
|
|
|
|
pop rax |
|
|
|
|
mov qword [r12], rax |
|
|
|
|
pop rax |
|
|
|
|
mov qword [rax], rbx |
|
|
|
|
mov qword [rax], rsi |
|
|
|
|
.end: |
|
|
|
|
inc rbx |
|
|
|
|
inc rsi |
|
|
|
|
add r12, 8 |
|
|
|
|
cmp byte [rbx], 0 |
|
|
|
|
cmp byte [rsi], 0 |
|
|
|
|
jnz _jump_loop |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
lea rbx, [bf_program] |
|
|
|
|
lea rsi, [bf_tape] |
|
|
|
|
lea rsi, [bf_program] |
|
|
|
|
lea rdi, [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: |
|
|
|
|
movzx rax, byte [rbx] |
|
|
|
|
movzx rax, byte [rsi] |
|
|
|
|
lea rax, [bf_instructions + 8*rax] |
|
|
|
|
call rax |
|
|
|
|
jmp _program_loop |
|
|
|
|
jmp rax |
|
|
|
|
|
|
|
|
|
xor rdi, rdi |
|
|
|
|
call exit |
|
|
|
|
|