Функция печати ASM с использованием вызовов b ios - PullRequest
2 голосов
/ 20 июня 2020

Я пытаюсь добавить функцию печати в ядро ​​ASM, которое я пишу, хотя я пробовал многие безуспешно. Большинство, например, из osdev , просто распечатывают:? Или два счастливых лица. Я использую загрузчик mikeos и qemu. Это мое текущее ядро, которое бесконечно распечатывает gibberi sh:

%include "print.asm"

os_main:
    hello db "Hi!", 0
    mov si, hello
    call print
    jmp $

Содержимое print.asm (из учебника):

print:
    pusha

; keep this in mind:
; while (string[i] != 0) { print string[i]; i++ }

; the comparison for string end (null byte)
start:
    mov al, [bx] ; 'bx' is the base address for the string
    cmp al, 0 
    je done

    ; the part where we print with the BIOS help
    mov ah, 0x0e
    int 0x10 ; 'al' already contains the char

    ; increment pointer and do next loop
    add bx, 1
    jmp start

done:
    popa
    ret



print_nl:
    pusha
    
    mov ah, 0x0e
    mov al, 0x0a ; newline char
    int 0x10
    mov al, 0x0d ; carriage return
    int 0x10
    
    popa
    ret

Что не так с этим кодом ? Я новичок в ассемблере, любая помощь приветствуется.

Компилятор: nasm

1 Ответ

1 голос
/ 21 июня 2020

В этом коде 2 ошибки.

os_main:
 hello db "Hi!", 0
 mov si, hello
 call print
 jmp $

Вы поместили строку на метку hello в пути выполнения программы! ЦП выполнит эти 4 байта («H», «i», «!», 0), как если бы они представляли инструкции. Очевидно, нет. Следовательно, вывод gibberi sh.

Это будет работать:

os_main:
 mov si, hello
 call print
 jmp $
 hello db "Hi!", 0

Как и в комментарии fuz, код print неверен в том, что он использует регистр неправильного адреса (BX), соответствующий вашему звонку (SI).

Лучше использовать следующий код:

; IN (si) OUT ()
print:
    pusha
    mov  bx, 0007h   ; BH is DisplayPage, BL is GraphicsColor
  start:
    mov  al, [si]    ; <<<<<<<<<
    cmp  al, 0 
    je   done
    mov  ah, 0x0E    ; BIOS.Teletype
    int  0x10
    inc  si          ; <<<<<<<<<
    jmp  start
  done:
    popa
    ret

; IN () OUT ()
print_nl:
    pusha
    mov  bh, 0       ; BH is DisplayPage (No need for GraphicsColor in BL)
    mov  ax, 0x0E0D  ; BIOS.Teletype CR
    int  0x10
    mov  ax, 0x0E0A  ; BIOS.Teletype LF
    int  0x10
    popa
    ret
...