;ds:si: pointer to asciiz string containing HQ9++ source code ExecuteHQ9: push ax push dx push si push di push es push bx mov bx, si .interpret: lodsb cmp al, 'H' je .doHelloWorld cmp al, 'Q' je .doPrintCode cmp al, '9' je .doDrinkBeer cmp al, '+' je .doCounter pop bx pop es pop di pop si pop dx pop ax ret .doHelloWorld: push ds mov ax, cs mov ds, ax push si mov si, .dataHelloWorld call .printString pop si pop ds jmp .interpret .doPrintCode: push si mov si, bx call .printString pop si jmp .interpret .doDrinkBeer: push ds push si push ax mov ax, cs mov ds, ax mov ax, 99 .beer_loop: call .printHexNumber mov si, .dataBeerSong1 call .printString call .printHexNumber mov si, .dataBeerSong2 call .printString dec ax call .printHexNumber mov si, .dataBeerSong3 call .printString test ax, ax jnz .beer_loop pop ax pop si pop ds jmp .interpret .doCounter: push ax inc ax pop ax jmp .interpret .printString: push ax push si .looping: lodsb test al, al jz .done mov ah, 0Eh int 10h jmp .looping .done: pop si pop ax ret .printHexNumber: pusha push ds mov ax, cs mov ds, ax push word 0 mov bx, ax xor dx, dx mov cx, 4r .convert_loop: mov ax, bx and ax, 0Fh cmp ax, 9 ja .greater_than_9 add ax, '0' jmp .converted .greater_than_9: add ax, 'A'-0Ah .converted: push ax shr bx, 4 dec cx jnz .convert_loop .popoff: pop ax cmp ax, 0 je .done mov ah, 0Eh int 10h jmp .popoff .done: pop ds popa ret .dataHelloWorld: db "Hello World!", 0 .dataBeerSong1: db " bottles of beer on the wall ", 0 .dataBeerSong2: db " bottles of beer", 13, 10, "Take one down, pass it around " .dataBeerSong3: db 0, " bottles of beer on the wall", 0