1) Регистр BX не содержит символ, который вы хотите напечатать, но содержит адрес памяти, где находится символ, который вы хотите напечатать (@HELLO_MSG). Таким образом, вы действительно хотите сказать не «mov al, bl», а «mov al, [bx]», то есть
«Установить AL в байт, хранящийся по адресу памяти BX» (mov AL , [BX])
2) Регистр BX используется B IOS для цветового компонента, с которым он телетипируется. Вы не можете использовать этот регистр в качестве индекса для памяти в HELLO_MSG. Вместо этого попробуйте использовать регистр SI - "mov al, [SI]".
3) Для каждого l oop вам необходимо, чтобы программа переместилась к следующему символу в строке, чтобы он одновременно печатал следующий символ и сравнил следующий символ с «0», так что вам нужно увеличить регистр индексации (SI, как я предлагаю в пункте 2). Поэтому вам нужно поместить инструкцию "in c si" где-то после установки al и перед переходом jne.
4) Вы также неправильно используете стек. Инструкция pusha поместит все регистры в стек sh, и они будут помещены в стек в определенном порядке c. Лучший способ получить обратно из пуша - это попа. Если вы вставите bx, вы будете вставлять в стек то, что было по оси на оси, и указатель стека будет не синхронизирован c примерно на 10 байтов или около того. Я бы даже не использовал стек.
Вот как я буду делать то, что вы пытаетесь сделать:
pusha ; save all the registers to the stack
mov si, HELLO_MSG ; set SI to to the address of the message
printstr:
mov ah, 0x0e ; BIOS teletype output
mov bh, 00h ; teletyping to the default page at B800h (IBM PC)
mov bl, 07h ; the CGA colour white
mov al,[si] ; put byte of memory address si into al
int 0x10 ; print it.
inc si
cmp al, 0 ; Compare if its a string termination character?
jne printstr ; if not go back to top
popa ; retrieve all the registers from the stack
ret ; return to the caller?
; Data
HELLO_MSG:
db 'Hello world!', 0
Обратите внимание, что я использую pusha и popa просто для демонстрации их использования. Поскольку я использую только ax, bx и si, было бы дешевле сделать три нажатия этих регистров и три всплывающих окна в конце, если бы действительно было необходимо сохранить эти регистры в контексте полной программы. Я стараюсь писать так, чтобы регистры могли быть немедленно сброшены, если сохранение их содержимого не является неизбежной необходимостью.