diff --git a/jitfuck.asm b/jitfuck.asm index 4c89e66..ad36565 100644 --- a/jitfuck.asm +++ b/jitfuck.asm @@ -1,24 +1,43 @@ format ELF64 executable - RIGHT = 3Eh - LEFT = 3Ch - PLUS = 2Bh - MINUS = 2Dh - DOT = 2Eh - COMMA = 2Ch - LBRAC = 5Bh - RBRAC = 5Dh + RIGHT = 0x3E + LEFT = 0x3C + PLUS = 0x2B + MINUS = 0x2D + DOT = 0x2E + COMMA = 0x2C + LBRAC = 0x5B + RBRAC = 0x5D - CHUNK_MAX = 20h + CHUNK_MAX = 0x40 CHUNK_SIZE = (CHUNK_MAX * 2) CHUNK_MASK = (CHUNK_SIZE - 1) - MAX_CHUNKS = 20h - TRANSLATION_MAX = 40h + MAX_CHUNKS = 0x20 - MEM = 100h + MEM = 0x100 entry $ + mov rdi,0 + mov rsi,(CHUNK_SIZE * MAX_CHUNKS) + mov rdx,0x07 ; PROT_READ | PROT_WRITE | PROT_EXEC + mov r10,0x22 ; MAP_PRIVATE | MAP_ANONYMOUS + mov r8,-1 + mov r9,0 + mov rax,9 ; mmap + syscall + cmp rax,-1 + je fail + mov [translations],rax + xor rbx,rbx +.kekw: + cmp rbx,(CHUNK_SIZE * MAX_CHUNKS) + jge .kekwdone + mov byte [rax+rbx],0 + inc rbx + jmp .kekw +.kekwdone: + xor r12,r12 ; Initialize chunk start .next_chunk: xor r13,r13 ; Initialize chunk offset @@ -26,7 +45,7 @@ entry $ call key .next_run: cmp rax,0 - je interpret ; EOF -> finished loading chunks + je execute ; EOF -> finished loading chunks ;; Dispatch on command cmp rax,RIGHT @@ -81,7 +100,7 @@ entry $ pop rax ; Pop address of lbrac's dest field mov rbx,r12 add rbx,CHUNK_SIZE - mov word [rax],bx ; Write start of next chunk to lbrac's dest field + mov word [rax],bx ; Write start of next chunk to lbrac's dest mov rax,r12 add rax,r13 mov byte [chunks+rax],RBRAC ; Write command @@ -91,85 +110,217 @@ entry $ jmp .end_chunk .end_chunk: - mov word [chunks+rax+4],0 ; Write chunk terminator add r12,CHUNK_SIZE ; Bump chunk start to next chunk jmp .next_chunk -interpret: +execute: + mov rax,r12 + add rax,r13 + mov word [chunks+rax+4],0 ; Terminate last chunk + add r12,CHUNK_SIZE + + xor rax,rax + mov rbx,[translations] +.init_translations: + cmp rax,r12 + je .begin + mov word [rbx+rax],0x0B0F ; Write UD2 to start + add rax,CHUNK_SIZE + jmp .init_translations +.begin: + mov r15,r12 ; Save end point xor r12,r12 ; Initialize code offset mov r13,mem ; Initialize head -.opcode_dispatch: - mov word ax,[chunks+r12] - movzx ebx,ah - cmp al,RIGHT - je .right - cmp al,LEFT - je .left - cmp al,PLUS - je .plus - cmp al,MINUS - je .minus - cmp al,DOT - je .dot - cmp al,COMMA - je .comma - cmp al,LBRAC - je .lbrac - cmp al,RBRAC - je .rbrac - jmp exit -.right: - add r13,rbx - jmp .next +.check: + cmp r12,r15 + je dump + mov rbx,[translations] + mov word ax,[rbx+r12] + cmp ax,0x0B0F + je translate +.run: + ;jmp .next_chunk -.left: - sub r13,rbx - jmp .next - -.plus: - add byte [r13],bl - jmp .next - -.minus: - sub byte [r13],bl - jmp .next - -.dot: - mov r14,rbx -.dot_loop: - cmp r14,0 - je .next - call emit - dec r14 - jmp .dot_loop - -.comma: ; TODO - int3 - jmp .next - -.lbrac: - cmp byte [r13],0 - jne .next_chunk - mov word r12w,[chunks+r12+2] - jmp .opcode_dispatch - -.rbrac: - cmp byte [r13],0 - je .next_chunk - mov word r12w,[chunks+r12+2] - jmp .opcode_dispatch - -.next: - add r12,2 - jmp .opcode_dispatch + mov r14,.check + mov rbx,[translations] + add rbx,r12 + jmp rbx .next_chunk: and r12,(not CHUNK_MASK) add r12,CHUNK_SIZE - jmp .opcode_dispatch + jmp .check -exit: +translate: + mov r14,[translations] + add r14,r12 ; Initialize translation write offset +.opcode: + mov word ax,[chunks+r12] + movzx ebx,ah + cmp al,RIGHT + je right + cmp al,LEFT + je left + cmp al,PLUS + je plus + cmp al,MINUS + je minus + cmp al,DOT + je dot + cmp al,COMMA + je comma + cmp al,LBRAC + je lbrac + cmp al,RBRAC + je rbrac + cmp al,0 + je term + jmp fail + +.next: + add r12,2 + jmp .opcode + +write: + cmp rdi,rsi + je .done + mov byte dl,[rdi] + mov byte [r14],dl + inc rdi + inc r14 + jmp write +.done: + ret + +right: + mov rdi,.translation_start + mov rsi,.translation_end + call write + mov byte [r14-4],bl + jmp translate.next +.translation_start: + add r13,0xFF +.translation_end: + +left: + mov rdi,.translation_start + mov rsi,.translation_end + call write + mov byte [r14-4],bl + jmp translate.next +.translation_start: + sub r13,0xFF +.translation_end: + +plus: + mov rdi,.translation_start + mov rsi,.translation_end + call write + mov byte [r14-1],bl + jmp translate.next +.translation_start: + add byte [r13],0xFF +.translation_end: + +minus: + mov rdi,.translation_start + mov rsi,.translation_end + call write + mov byte [r14-1],bl + jmp translate.next +.translation_start: + sub byte [r13],0xFF +.translation_end: + +dot: + mov rsi,.translation_end +.loop: + cmp rbx,0 + je translate.next + mov rdi,.translation_start + call write + dec rbx + jmp .loop +.rt_impl: + mov rdi,1 + mov rsi,r13 + mov rdx,1 + mov rax,1 + syscall + ret +.translation_start: + mov rax,.rt_impl + call rax +.translation_end: + +comma: ; TODO + int3 + jmp translate.next + +lbrac: + mov rdi,.translation_start + mov rsi,.translation_end + call write + mov word ax,[chunks+r12+2] + mov byte [r14-7],al + shr rax,8 + mov byte [r14-6],al + and r12,(not CHUNK_MASK) + jmp execute.run +.translation_start: + cmp byte [r13],0 + je .jump + add r12,(CHUNK_SIZE) + jmp r14 +.jump: + mov r12,0xFFFF + jmp r14 +.translation_end: + +rbrac: + mov rdi,.translation_start + mov rsi,.translation_end + call write + mov word ax,[chunks+r12+2] + mov byte [r14-7],al + shr rax,8 + mov byte [r14-6],al + and r12,(not CHUNK_MASK) + jmp execute.run +.translation_start: + cmp byte [r13],0 + jne .jump + add r12,(CHUNK_SIZE) + jmp r14 +.jump: + mov r12,0xFFFF + jmp r14 +.translation_end: + +term: + mov rdi,.translation_start + mov rsi,.translation_end + call write + and r12,(not CHUNK_MASK) + jmp execute.run +.translation_start: + mov rdi,0 + mov rax,60 + syscall +.translation_end: + +fail: + mov rdi,1 + mov rax,60 + syscall + +dump: + mov rdi,1 + mov rsi,[translations] + mov rdx,(CHUNK_SIZE * MAX_CHUNKS) + mov rax,1 + syscall mov rdi,0 mov rax,60 syscall @@ -189,14 +340,7 @@ key: ret .ch: rb 1 -emit: - mov rdi,1 - mov rsi,r13 - mov rdx,1 - mov rax,1 - syscall - ret +chunks: rw (CHUNK_MAX * MAX_CHUNKS) +mem: db MEM dup 0 -chunks: rw (CHUNK_MAX * MAX_CHUNKS) -translations: rb (TRANSLATION_MAX * MAX_CHUNKS) -mem: db MEM dup 0 +translations: rq 1