使用 bios 调用的 ASM 打印功能
ASM print function using bios calls
我正在尝试将打印功能添加到我正在编写的 ASM 内核中,尽管我尝试了很多次都没有成功。大多数,例如 osdev 中的那个,只需打印出:?,或两个笑脸。我正在使用 mikeos 引导加载程序和 qemu。这是我当前的内核,它无限地打印出乱码:
%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
此代码中有 2 个错误。
os_main:
hello db "Hi!", 0
mov si, hello
call print
jmp $
您已将字符串放在程序执行路径中的标签 hello 处! CPU 将执行这 4 个字节(“H”、“i”、“!”、0),就好像它们代表指令一样。显然他们不是。因此输出的是乱码。
这会起作用:
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
我正在尝试将打印功能添加到我正在编写的 ASM 内核中,尽管我尝试了很多次都没有成功。大多数,例如 osdev 中的那个,只需打印出:?,或两个笑脸。我正在使用 mikeos 引导加载程序和 qemu。这是我当前的内核,它无限地打印出乱码:
%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
此代码中有 2 个错误。
os_main: hello db "Hi!", 0 mov si, hello call print jmp $
您已将字符串放在程序执行路径中的标签 hello 处! CPU 将执行这 4 个字节(“H”、“i”、“!”、0),就好像它们代表指令一样。显然他们不是。因此输出的是乱码。
这会起作用:
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