use16 org 100h macro print_string s { mov dx, s mov ah, 9 int 21h } macro print_char chr { mov dl, chr mov ah, 02h int 21h } macro cmpje reg, tmpl, trgt { cmp reg, tmpl je trgt } macro cmpjne reg, tmpl, trgt { cmp reg, tmpl jne trgt } macro failwith_equal reason { mov dx, reason je error } macro failwith reason { mov dx, reason jmp error } ; entry point mov si, prg ; si - instruction pointer mov di, mem ; di - data pointer mov bx, br_stack; bx - stack pointer start: mov al, [si] and al, al jz terminate call proc inc si jmp start error: mov ah, 9 int 21h terminate: mov ah, 4ch int 21h proc: cmpje al, '>', right cmpje al, '<', left cmpje al, '+', incr cmpje al, '-', decr cmpje al, ',', read cmpje al, '.', print cmpje al, '[', open cmpje al, ']', close ret right: inc di cmpjne di, mem_end, right1 mov di, mem right1: ret left: cmpjne di, mem, left1 mov di, mem_end left1: dec di ret incr: inc byte ptr di ret decr: dec byte ptr di ret read: mov ah, 01h int 21h mov [di], al ret print: mov dl, [di] mov ah, 02h int 21h ret open: cmpje byte ptr di, 0, find_close cmp bx, br_stack_end failwith_equal er_full mov [bx], si add bx, 2 ret find_close: xor cx, cx l: lodsb ; al := *si++ cmpjne al, '[', l2 inc cx jmp l l2: cmpjne al, ']', l3 dec cx jnz l sub bx, 2 dec si ret l3: and al, al jnz l failwith er_end close: cmpje byte ptr di, 0, close1 cmp bx, br_stack failwith_equal er_empty sub bx, 2 mov si, [bx] dec si close1: ret er_end: db 'End reached unexpectedly$' er_empty: db 'Stack underflow$' er_full: db 'Stack overflow$' msg_debug: db ' debug $' prg: db ',>,[-<+>]<.', 0 br_stack: dw 1024 dup (0ffffh) br_stack_end: mem: db 32768 dup (0) mem_end: