Lectura desde la memoria en modo real 8086 mientras se usa 'ORG 0x0000'

He estado jugando con el ensamblaje x86-16 y ejecutándolo con VirtualBox. Por alguna razón, cuando leo de memoria e intento imprimirlo como un personaje, obtengo resultados completamente diferentes de lo que esperaba. Sin embargo, cuando codifico el personaje como parte de la instrucción, funciona bien. Aquí está el 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

La etiqueta de impresión y las instrucciones que contiene pueden ignorarse ya que aún no la he usado debido al problema que he tenido al intentar imprimir un carácter almacenado en la memoria. Lo he ensamblado con FASM y NASM y tengo el mismo problema, lo que significa que obviamente es mi culpa.

Imprime algo como:

Respuestas a la pregunta(1)

Su respuesta a la pregunta