.data .org 0x10 inputdata: ;4 8 * 8 .fill 1, 0x34382A38 ;8 * X 1 .fill 1, 0x382A5831 ;- X D + .fill 1, 0x2D58442B ;D J \xF8 P .fill 1, 0x444AF850 ;6 8 * + .fill 1, 0x36382A2B ;D I \020 \000 .fill 1, 0x44492000 ;\000 \000 < ~ .fill 1, 0x00003C7E ;J \005 P 8 .fill 1, 0x4A055038 ;8 * .fill 1, 0x382A stack: .fill 256, 0 jumptable: ;0 .fill 0, vm_eof .fill 40, vm_default ;42 .fill 1, vm_mul ;43 .fill 1, vm_add ;44 .fill 1, vm_default ;45 .fill 1, vm_sub ;46-47 .fill 2, vm_default ;48-57 .fill 10, vm_consts ;58-59 .fill 2, vm_default ;60 .fill 1, vm_lessthan ;61-67 .fill 7, vm_default ;68 .fill 1, vm_dup ;69-72 .fill 4, vm_default ;73 .fill 1, vm_imm ;74 .fill 1, vm_jmp ;75-79 .fill 5, vm_default ;80 .fill 1, vm_pop ;81-87 .fill 7, vm_default ;88 .fill 1, vm_xch ;88-125 .fill 40, vm_default ;126 .fill 1, vm_not ;127-255 .fill 129, vm_default .text main: ldi r1, inputdata call+ vm br+ main vm: ;r1 ... addr to input ;r2 ... pc ;r3 ... effective stack address ;r4 ... effective input addr ;r5 ... input ;set pc to -4 ldis r2, 0xFFFF ;load base address of stack ldi r3, stack vm_default: vm_loop: ;increment pc addi r2, r2, 1 ;generate effective input addr add r4, r1, r2 ;load input ldw r5, 0(r4) ;jump to instr brr r5 vm_eof: ;load stack[sp-1] ldw r0, 0-4(r3); ret+; ;case * ;42 vm_mul: br+ vm_loop ;case + ;43 vm_add: ;decrement sp subi r3, r3, 4 ;load sp ldw r6, 0(r3) ;load sp-1 ldw r7, 0-4(r3) ;sp-1 = sp-1 + sp add r7, r7, r6 ;store sp-1 stw r7, 0-4(r3) br+ vm_loop ;case - ;45 vm_sub: ;decrement sp subi r3, r3, 4 ;load sp ldw r6, 0(r3) ;load sp-1 ldw r7, 0-4(r3) ;sp-1 = sp-1 - sp sub r7, r7, r6 ;store sp-1 stw r7, 0-4(r3) br+ vm_loop ;case 0 1 2 3 4 5 6 7 8 9 ;48-57 vm_consts: ;input minus offset subi r6, r5, 48 ;store onto stack stw r6, 0(r3) ;increment stack addr addi r3, r3, 4 br+ vm_loop ;case < ;60 vm_lessthan: ;decrement sp subi r3, r3, 4 ;load sp ldw r6, 0(r3) ;load sp-1 ldw r7, 0-4(r3) ;load r8 with 0 ldi r8, 0 ;compare sp-1 with sp cmp r7, r6 ;set r8 to -1 if less than ldilt r8, 1 ;store r8 to sp-1 stw r8, 0-4(r3) br+ vm_loop ;case D ;68 vm_dup: ;load sp-1 ldw r6, 0-4(r3) ;store to sp stw r6, 0(r3) ;increment stack addr addi r3, r3, 4 br+ vm_loop ;case I ;73 vm_imm: ;load new high byte ldb r6, 4(pc) ;shift high byte lls r6, r6, 8 ;load 2nd byte ldb r7, 3(pc) ;add to high byte add r6, r6, r7 ;shift lls r6, r6, 8 ;load ldb r7, 2(pc) ;add add r6, r6, r7 ;shift lls r6, r6, 8 ;load ldb r7, 1(pc) ;add add r6, r6, r7 ;store result to stack stw r6, 0(r3) ;pc+4 addi r2, r2, 4 br+ vm_loop ;case J ;74 vm_jmp: ;decrement sp sub r3, r3, 4 ;load sp ldw r6, 0(r3) ;compare to 0 cmpi r6,0 ;increment pc if == 0 addieqD r2, r2, 4 brnq+ vm_loop ;if != 0 ;load pc+1 input ldb r6, 1(r4) ;pc += data add r2, r2, r6 br+ vm_loop ;case P ;80 vm_pop: ;decrement stack addr subi r3, r3, 4 br+ vm_loop ;case X ;88 vm_xch: ;load sp-1 ldw r6, 0-4(r3) ;load sp-2 ldw r7, 0-8(r3) ;store sp-1 to sp-2 stw r6, 0-8(r3) ;store sp-2 to sp-1 stw r7, 0-4(r3) br+ vm_loop ;case ~ ;126 vm_not: ldw r6, 0-4(r3) not r6 stw r6, 0-4(r3) br+ vm_loop