gpt4 book ai didi

assembly - 引导加载程序的奇怪行为

转载 作者:行者123 更新时间:2023-12-02 22:15:35 27 4
gpt4 key购买 nike

我一直在尝试设计一个简单的操作系统,只有引导扇区和带有中断的16位实模式。我终于能够制作操作系统/引导加载程序,我在虚拟盒中测试了它,并且它有效。

然后我将镜像刻录到 CD,并将其启动到我的旧台式机,该台式机配备 Pentium 4、BIOS 版本 A05 和 1GB RAM,并且它工作得很好 - 一个简单的操作系统,可以将“ header ”打印到它位于屏幕顶部,它的作用是让您在屏幕上打字,并注册几个键来导航光标。

然后,我将光盘插入我用了 1 年的笔记本电脑,配备 i5 处理器、2.6 GB RAM 和 A05 BIOS 修订版,光标似乎随机移动,高速打印随机字符,最后停在anscii 字符 235(扩展字符表的一部分),此时键盘工作正常,指定用于移动光标的键工作正常,只有标题。这是我测试、编译、写入、刻录 CD 的计算机。 (我使用的是Linux Mint 12操作系统)

我已经跳过了我认为需要做的所有“障碍”:制作了一个遵循 El Torito“无仿真”启动标准、启动签名、512 字节的 iso 镜像,并写入了正确的扇区。

这是我的代码有问题吗,我没有做些什么,还是这只是正常现象?

这是我的代码(NASM x86 语法):

    ;**************************
; Note OS, Experimental OS
;**************************
[org 0x7C00]
[bits 16]
start:
jmp loader ;jump to the actual start of bootloader
times 8 - ($ - $$) db 0 ;pad eight bytes

;*********************
;El Torito Boot Info Table
;*********************

;in nasm, I couldn't figure out how to reserve bytes, in the middle of .text
;so I zeroed it out.
times 56 db 0

loader:
call cls ;clear the screen
mov si, head1 ;setup page headers
call printf
mov si, head2
call printf
jmp note ;start note program

cls:
mov ah, 0x0F ;get current video mode
mov al, 0x00 ;reset register
int 0x10 ;get video mode
mov ah, 0x00 ;set video mode
int 0x10 ;reset screen
mov ah, 0x02 ;set cursor pos
mov bh, 0x00 ;page 00
mov dh, 0x00 ;row 00
mov dl, 0x00 ;col. 00
int 0x10 ;set pos
ret

printf:
.loop ;our function that loops
mov al, [si] ;load byte
cmp al, 0 ;if null, end
je .end
mov ah, 0x0E ;function 0E
mov bh, 0x00 ;page 0x00
mov bl, 0x0F ;white text on black background
int 0x10 ;print
inc si ;increment source index
jmp .loop ;repeat
.end
ret ;return

;*******************
; Note 'Program'
;*******************

note:
mov ah, 0x00 ;function 00
int 0x16 ;get character
cmp al, '`' ;go up line?
je setcur
cmp al, 0x0D ;enter?
je setent
cmp al, '+' ;plus?
je setplu
cmp al, '-' ;minus?
je setminu
cmp al, '\' ;reset?
je loader
cmp al, 0x08 ;backspace?
je setback
mov ah, 0x0E ;function 0E
mov bh, 0x00 ;page 00
mov bl, 0x0F ;white on black
int 0x10 ;print
jmp note ;repeat

setcur:
mov ah, 0x03 ;get cur pos
mov bh, 0x00 ;page 00
int 0x10 ;get pos
cmp dh, 0x00 ;are we at top of page?
je .begin ;just reset cursor if so
sub dh, 0x01 ;go up one line
.begin
mov dl, 0x00 ;set to beginning of line
mov ah, 0x02 ;set cursor function
mov bh, 0x00 ;page 00
int 0x10 ;set position
jmp note ;read next character

setent:
mov ah, 0x0E ;write character
mov al, 0x0A ;begin line
mov bh, 0x00 ;page 00
mov bl, 0x0F ;white on black
int 0x10 ;print

setplu:
mov ah, 0x03 ;get cursor pos
mov bh, 0x00 ;page 0x00
int 0x10 ;get pos
mov ah, 0x02 ;set cursor pos
add dl, 0x01 ;add one to column
int 0x10 ;set new pos
jmp note ;get next char

setminu:
mov ah, 0x03 ;get cursor pos
mov bh, 0x00 ;page 00
int 0x10 ;get pos
mov ah, 0x02 ;set cursor pos
sub dl, 0x01 ;sub one to column
int 0x10 ;set new pos
jmp note ;get next char

setback:
mov ah, 0x03 ;get cursor pos
mov bh, 0x00 ;page 00
int 0x10 ;get pos
mov ah, 0x02 ;set cursor pos
sub dl, 0x01 ;sub one column
int 0x10 ;set pos
mov ah, 0x0E ;write char
mov al, ' ' ;write space
mov bh, 0x00 ;page 00
mov bl, 0x0F ;white on black
int 0x10
mov ah, 0x02 ;reset cur pos
int 0x10 ;reset
jmp note

;******************
; Our Page Headers
;******************
head1: db '- Note OS Version 1.2-', 0x0A, 0x0D, 0
head2: db '=======================', 0x0A, 0x0D, 0x0A, 0x0D, 0

times 510 - ($ - $$) db 0
dw 0xAA55

供引用(我引用的东西):

Anscii 表:http://www.asciitable.com/

El-Torito 信息:http://wiki.osdev.org/El-Torito

编辑:以下是我编程的按键及其作用:

输入 - 现在可以正常工作退格键 - 现在可以正常工作加号 - 向右移动光标减号 - 向左移动光标` - 将光标移动到上一行的开头\- “软重启”几乎跳转到加载程序的开头

最佳答案

问题出在这里:

[org 0x7C00]
...
start:
jmp loader ;jump to the actual start of bootloader
...
loader:
call cls ;clear the screen
mov si, head1 ;setup page headers
call printf
...
printf:
.loop ;our function that loops
mov al, [si] ;load byte

当代码启动时,您期望CS=DS=0。 DS 不保证为 0。因此,当它非零时,mov al, [si] 从段 0 以外的某个段读取字节,并且可能存在一些垃圾,而不是问候消息的副本.

此外,某些 BIOS 使用 0:0x7C00 地址跳转到您的代码,而其他 BIOS 使用 0x7C0:0,这意味着即使 CS 也不能保证有固定值。

我会做的是这样的:

[org 0x7C00]
[bits 16]
start:
jmp loader ;jump to the actual start of bootloader
...
loader:
jmp 0:loader2 ; this far jump guarantees CS=0

loader2:
push cs
pop ds ; this guarantees DS=0

; the rest of the code goes here

关于assembly - 引导加载程序的奇怪行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9660315/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com