我的操作系统显示奇怪的字符
My operating system is showing weird characters
现在我正在用汇编编程我的操作系统,我试图将它加载到闪存驱动器中。但是当我尝试启动操作系统时,它显示奇怪的字符。
汇编代码:
https://github.com/Zahon7/ZahonOS/blob/main/ZahonOS.asm
[org 0x7c00]
call newline
call newline
call newline
call newline
call newline
call newline
call newline
call newline
call newline
call newline
call newline
call newline
mov bx, bm1
call printf
mov bx, bm2
call printf
call cls
mov bh, 70h
call color
mov bx, welmsg
call printf
wywtd:
mov bx, welmsg2
call printf
call waitforkey
cmp al, 49
je reboot
cmp al, 50
je guess
mov bx, invalidmsg
call printf
call waitforkey
call cls
mov bh, 70h
call color
call wywtd
jmp $
good:
mov bx, okans
call printf
call waitforkey
call reboot
guess:
call cls
mov bh, 70h
call color
mov bx, gmsg
call printf
call waitforkey
cmp al, 49
je good
mov bx, wrongans
call printf
call waitforkey
call reboot
reboot:
db 0x0ea
dw 0x0000
dw 0xffff
newline:
mov bx, nl
call printf
ret
color:
mov ah, 06h
xor al, al
xor cx, cx
mov dx, 184FH
; mov bh, 1Fh
int 10h
ret
waitforkey:
mov ah, 00h
int 16h
ret
cls:
pusha
mov ah, 0x00
mov al, 0x03
int 0x10
popa
ret
printf:
mov ah, 0x0e
.Loop:
cmp [bx], byte 0
je .Exit
mov al, [bx]
int 0x10
inc bx
jmp .Loop
.Exit:
ret
okans: db "Correct answer!", 0x00
wrongans: db "Wrong answer!", 0x00
gmsg: db "What is 78 * 23?", 0x0a, 0x0d, "[1] 1794", 0x0a, 0x0d, "[2] 1894", 0x0a, 0x0d, "[3] 1872", 0x0a, 0x0d, 0x00
invalidmsg: db "Invalid option!", 0x0a, 0x0d, 0x00
nl: db 0x0a, 0x0d, 0x00
welmsg: db "Welcome to ZahonOS Light edition!", 0x0a, 0x0d, 0x00
welmsg2: db "what do you want to do?", 0x0a, 0x0d, "[1] Restart", 0x0a, 0x0d, "[2] Game", 0x0a, 0x0d, 0x0a, 0x0d, "Answer: ", 0x00
bm1: db "Booting ZahonOS Light edition...", 0x0a, 0x0d, 0x00
bm2: db "Done!", 0x00
times 510-($-$$) db 0
dw 0xaa55
这也是我关于堆栈溢出的第一个问题。
How it looks
What it should look like
当引导扇区程序开始时,不能相信段寄存器包含任何特定值。根据你的[org 0x7c00]
和你进一步用于寻址内存的指令,DS
段寄存器需要包含0。你必须自己设置它:
xor ax, ax
mov ds, ax
mov es, ax
同样,您的程序经常访问堆栈,但您不确定 pre-existing 堆栈是否能胜任该任务。您必须自己设置:
xor ax, ax
mov ss, ax
mov sp, 0x7C00 ; Right below the bootsector
BIOS.Teletype 函数 0Eh 已经使用 BL
和 BH
寄存器(它们一起构成 BX
)作为它的一些参数。因此,最好使用 SI
寄存器作为您提供给 printf.
的指针
在处理无效答案后,您使用 call wywtd
再次重复。在这种情况下,不 call 而是 jump 更有意义:
jmp wywtd
我不知道这是不是故意的,但是 bm1 和 bm2 消息会在您清屏后立即被删除...
call reboot
reboot:
这个call reboot
是多余的。执行也可以进入 reboot:.
newline:
mov SI, nl
call printf
ret
您可以用跳转 jmp printf
.
替换此 so-called 尾调用
但最有效的方法是将 newline 代码直接放在 printf 代码之上。这甚至会削减 jmp printf
:
newline:
mov SI, nl
printf:
...
[org 0x7c00]
xor ax, ax
mov ds, ax
mov es, ax
mov ss, ax
mov sp, 0x7C00
call newline
call newline
call newline
call newline
call newline
call newline
call newline
call newline
call newline
call newline
call newline
call newline
mov SI, bm1
call printf
mov SI, bm2
call printf
call cls
mov bh, 70h
call color
mov SI, welmsg
call printf
wywtd:
mov SI, welmsg2
call printf
call waitforkey
cmp al, 49
je reboot
cmp al, 50
je guess
mov SI, invalidmsg
call printf
call waitforkey
call cls
mov bh, 70h
call color
JMP wywtd
jmp $
good:
mov SI, okans
call printf
call waitforkey
call reboot
guess:
call cls
mov bh, 70h
call color
mov SI, gmsg
call printf
call waitforkey
cmp al, 49
je good
mov SI, wrongans
call printf
call waitforkey
reboot:
db 0x0ea
dw 0x0000
dw 0xffff
color:
mov ah, 06h
xor al, al
xor cx, cx
mov dx, 184FH
; mov bh, 1Fh
int 10h
ret
waitforkey:
mov ah, 00h
int 16h
ret
cls:
pusha
mov ah, 0x00
mov al, 0x03
int 0x10
popa
ret
newline:
mov SI, nl
printf:
mov ah, 0x0e
mov bx, 000Fh ; DisplayPage BH=0, GraphicsColor BL=15 (BrightWhiteOnBlack)
.Loop:
mov al, [SI]
test al, al
jz .Exit
int 0x10
inc SI
jmp .Loop
.Exit:
ret
okans: db "Correct answer!", 0x00
wrongans: db "Wrong answer!", 0x00
gmsg: db "What is 78 * 23?", 0x0a, 0x0d, "[1] 1794", 0x0a, 0x0d, "[2] 1894", 0x0a, 0x0d, "[3] 1872", 0x0a, 0x0d, 0x00
invalidmsg: db "Invalid option!", 0x0a, 0x0d, 0x00
nl: db 0x0a, 0x0d, 0x00
welmsg: db "Welcome to ZahonOS Light edition!", 0x0a, 0x0d, 0x00
welmsg2: db "what do you want to do?", 0x0a, 0x0d, "[1] Restart", 0x0a, 0x0d, "[2] Game", 0x0a, 0x0d, 0x0a, 0x0d, "Answer: ", 0x00
bm1: db "Booting ZahonOS Light edition...", 0x0a, 0x0d, 0x00
bm2: db "Done!", 0x00
times 510-($-$$) db 0
dw 0xaa55
现在我正在用汇编编程我的操作系统,我试图将它加载到闪存驱动器中。但是当我尝试启动操作系统时,它显示奇怪的字符。
汇编代码: https://github.com/Zahon7/ZahonOS/blob/main/ZahonOS.asm
[org 0x7c00]
call newline
call newline
call newline
call newline
call newline
call newline
call newline
call newline
call newline
call newline
call newline
call newline
mov bx, bm1
call printf
mov bx, bm2
call printf
call cls
mov bh, 70h
call color
mov bx, welmsg
call printf
wywtd:
mov bx, welmsg2
call printf
call waitforkey
cmp al, 49
je reboot
cmp al, 50
je guess
mov bx, invalidmsg
call printf
call waitforkey
call cls
mov bh, 70h
call color
call wywtd
jmp $
good:
mov bx, okans
call printf
call waitforkey
call reboot
guess:
call cls
mov bh, 70h
call color
mov bx, gmsg
call printf
call waitforkey
cmp al, 49
je good
mov bx, wrongans
call printf
call waitforkey
call reboot
reboot:
db 0x0ea
dw 0x0000
dw 0xffff
newline:
mov bx, nl
call printf
ret
color:
mov ah, 06h
xor al, al
xor cx, cx
mov dx, 184FH
; mov bh, 1Fh
int 10h
ret
waitforkey:
mov ah, 00h
int 16h
ret
cls:
pusha
mov ah, 0x00
mov al, 0x03
int 0x10
popa
ret
printf:
mov ah, 0x0e
.Loop:
cmp [bx], byte 0
je .Exit
mov al, [bx]
int 0x10
inc bx
jmp .Loop
.Exit:
ret
okans: db "Correct answer!", 0x00
wrongans: db "Wrong answer!", 0x00
gmsg: db "What is 78 * 23?", 0x0a, 0x0d, "[1] 1794", 0x0a, 0x0d, "[2] 1894", 0x0a, 0x0d, "[3] 1872", 0x0a, 0x0d, 0x00
invalidmsg: db "Invalid option!", 0x0a, 0x0d, 0x00
nl: db 0x0a, 0x0d, 0x00
welmsg: db "Welcome to ZahonOS Light edition!", 0x0a, 0x0d, 0x00
welmsg2: db "what do you want to do?", 0x0a, 0x0d, "[1] Restart", 0x0a, 0x0d, "[2] Game", 0x0a, 0x0d, 0x0a, 0x0d, "Answer: ", 0x00
bm1: db "Booting ZahonOS Light edition...", 0x0a, 0x0d, 0x00
bm2: db "Done!", 0x00
times 510-($-$$) db 0
dw 0xaa55
这也是我关于堆栈溢出的第一个问题。
How it looks
What it should look like
当引导扇区程序开始时,不能相信段寄存器包含任何特定值。根据你的[org 0x7c00]
和你进一步用于寻址内存的指令,DS
段寄存器需要包含0。你必须自己设置它:
xor ax, ax
mov ds, ax
mov es, ax
同样,您的程序经常访问堆栈,但您不确定 pre-existing 堆栈是否能胜任该任务。您必须自己设置:
xor ax, ax
mov ss, ax
mov sp, 0x7C00 ; Right below the bootsector
BIOS.Teletype 函数 0Eh 已经使用 BL
和 BH
寄存器(它们一起构成 BX
)作为它的一些参数。因此,最好使用 SI
寄存器作为您提供给 printf.
在处理无效答案后,您使用 call wywtd
再次重复。在这种情况下,不 call 而是 jump 更有意义:
jmp wywtd
我不知道这是不是故意的,但是 bm1 和 bm2 消息会在您清屏后立即被删除...
call reboot reboot:
这个call reboot
是多余的。执行也可以进入 reboot:.
newline: mov SI, nl call printf ret
您可以用跳转 jmp printf
.
替换此 so-called 尾调用
但最有效的方法是将 newline 代码直接放在 printf 代码之上。这甚至会削减 jmp printf
:
newline:
mov SI, nl
printf:
...
[org 0x7c00]
xor ax, ax
mov ds, ax
mov es, ax
mov ss, ax
mov sp, 0x7C00
call newline
call newline
call newline
call newline
call newline
call newline
call newline
call newline
call newline
call newline
call newline
call newline
mov SI, bm1
call printf
mov SI, bm2
call printf
call cls
mov bh, 70h
call color
mov SI, welmsg
call printf
wywtd:
mov SI, welmsg2
call printf
call waitforkey
cmp al, 49
je reboot
cmp al, 50
je guess
mov SI, invalidmsg
call printf
call waitforkey
call cls
mov bh, 70h
call color
JMP wywtd
jmp $
good:
mov SI, okans
call printf
call waitforkey
call reboot
guess:
call cls
mov bh, 70h
call color
mov SI, gmsg
call printf
call waitforkey
cmp al, 49
je good
mov SI, wrongans
call printf
call waitforkey
reboot:
db 0x0ea
dw 0x0000
dw 0xffff
color:
mov ah, 06h
xor al, al
xor cx, cx
mov dx, 184FH
; mov bh, 1Fh
int 10h
ret
waitforkey:
mov ah, 00h
int 16h
ret
cls:
pusha
mov ah, 0x00
mov al, 0x03
int 0x10
popa
ret
newline:
mov SI, nl
printf:
mov ah, 0x0e
mov bx, 000Fh ; DisplayPage BH=0, GraphicsColor BL=15 (BrightWhiteOnBlack)
.Loop:
mov al, [SI]
test al, al
jz .Exit
int 0x10
inc SI
jmp .Loop
.Exit:
ret
okans: db "Correct answer!", 0x00
wrongans: db "Wrong answer!", 0x00
gmsg: db "What is 78 * 23?", 0x0a, 0x0d, "[1] 1794", 0x0a, 0x0d, "[2] 1894", 0x0a, 0x0d, "[3] 1872", 0x0a, 0x0d, 0x00
invalidmsg: db "Invalid option!", 0x0a, 0x0d, 0x00
nl: db 0x0a, 0x0d, 0x00
welmsg: db "Welcome to ZahonOS Light edition!", 0x0a, 0x0d, 0x00
welmsg2: db "what do you want to do?", 0x0a, 0x0d, "[1] Restart", 0x0a, 0x0d, "[2] Game", 0x0a, 0x0d, 0x0a, 0x0d, "Answer: ", 0x00
bm1: db "Booting ZahonOS Light edition...", 0x0a, 0x0d, 0x00
bm2: db "Done!", 0x00
times 510-($-$$) db 0
dw 0xaa55