我的操作系统显示奇怪的字符

发布于 2025-01-11 20:30:20 字数 1468 浏览 0 评论 0原文

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

各自安好 2025-01-18 20:30:20

当引导扇区程序开始时,不能相信段寄存器包含任何特定值。根据您的[org 0x7c00]以及您进一步用于寻址内存的指令,DS段寄存器需要包含0。您必须自己设置它:

xor ax, ax
mov ds, ax
mov es, ax

类似,您的程序经常访问堆栈,但您不确定预先存在的堆栈是否能够胜任该任务。您必须自己进行设置:

xor ax, ax
mov ss, ax
mov sp, 0x7C00    ; Right below the bootsector

BIOS.Teletype 函数 0Eh 已使用 BLBH 寄存器(它们一起形成 BX)作为它的参数。因此,最好使用 SI 寄存器作为提供给 printf 的指针。

处理无效答案后,您可以使用 call wywtd 再次重复。在这种情况下,不调用而是跳转更有意义:

jmp wywtd

我不知道这是否是故意的,但是bm1bm2 消息会在您清除屏幕后立即删除...

 调用重启

重新启动:

这个调用reboot是多余的。执行也可以进入重新启动:。

<前><代码>换行符:
mov SI, nl
调用 printf
雷特

您可以用跳转 jmp printf 来替换这个所谓的尾调用
但最有效的方法是将 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

When a bootsector program begins, the segment registers cannot be trusted to contain any particular value. In accordance with your [org 0x7c00] and the instructions that you further use to address memory, the DS segment register needs to contain 0. You must set it up yourself:

xor ax, ax
mov ds, ax
mov es, ax

Similarly, your program accesses the stack a lot but you don't make sure that the pre-existing stack is up to that task. You must set it up yourself:

xor ax, ax
mov ss, ax
mov sp, 0x7C00    ; Right below the bootsector

The BIOS.Teletype function 0Eh already uses the BL and BH registers (together they form BX) as some of its parameters. Therefore it would be better to use the SI register as the pointer that you provide to your printf.

At the conclusion of processing an invalid answer you use call wywtd to repeat all over again. It makes more sense to not call but rather jump in this instance:

jmp wywtd

I don't know if this is on purpose, but the bm1 and bm2 messages are immediately erased by you clearing the screen...

  call reboot

reboot:

This call reboot is redundant. The execution can just as well fall through into reboot:.

newline:
  mov SI, nl
  call printf
  ret

You could replace this so-called tail call by a jump jmp printf.
But the most efficient would be to put the newline code directly above the printf code. That would shave off even the 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
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文