Leitura da memória no modo real 8086 ao usar 'ORG 0x0000'

Eu tenho mexido com o assembly x86-16 e executado com o VirtualBox. Por alguma razão, quando leio de memória e tento imprimi-lo como personagem, obtenho resultados completamente diferentes do que esperava. No entanto, quando codifico o caractere como parte da instrução, ele funciona bem. Aqui está o código:

ORG 0
BITS 16

push word 0xB800        ; Address of text screen video memory in real mode for colored monitors
push cs
pop ds                  ; ds = cs
pop es                  ; es = 0xB800
jmp start

; input = di (position*2), ax (character and attributes)
putchar:
    stosw
    ret

; input = si (NUL-terminated string)
print:
    cli
    cld
    .nextChar:
        lodsb   ; mov al, [ds:si] ; si += 1
        test al, al
        jz .finish
        call putchar
        jmp .nextChar
    .finish:
        sti
        ret

start:
    mov ah, 0x0E
    mov di, 8

    ; should print P
    mov al, byte [msg]
    call putchar

    ; should print A
    mov al, byte [msg + 1]
    call putchar

    ; should print O
    mov al, byte [msg + 2]
    call putchar

    ; should print !
    mov al, byte [msg + 3]
    call putchar

    ; should print X
    mov al, 'X'
    call putchar

    ; should print Y
    mov al, 'Y'
    call putchar

    cli
    hlt

msg: db 'PAO!', 0

; Fill the rest of the bytes upto byte 510 with 0s
times 510 - ($ - $) db 0

; Header
db 0x55
db 0xAA

A etiqueta de impressão e as instruções nela podem ser ignoradas, pois ainda não a usei devido ao problema que estou tentando imprimir um caractere armazenado na memória. Eu o montei com o FASM e o NASM e tenho o mesmo problema, o que significa que é obviamente minha culpa.

Imprime algo como:

questionAnswers(1)

yourAnswerToTheQuestion