我正在尝试了解操作系统的工作原理,因此我正在制作一些基本代码,以便在模拟软盘驱动器的bootsector上运行。当我运行代码时,存储在软盘的第一个扇区中的代码按预期执行;它打印字符串:“加载软盘”,但是当它加载下一段代码时,它不会打印字符串“Sector 2 loaded”,它只会使光标闪烁(这是预期的行为)。我正在使用Oracle VirtualBox来模拟带有软盘驱动器的系统,以及一个十六进制编辑器,将我的二进制文件合并到由NASM编译的单个.img文件中。代码被过度评论并且效率低下,目的是使代码中的每一位都清楚。 这是代码
引导扇区(0x0000-0x01FF):
org 0x7C00 ;Tell compiler that this is where code starts
bits 16 ;The CPU is in Real 16bit mode
jmp Start ;Skip over the string stored at the top of the program
Msg: db "Loading the floppy ... "
EndMsg:
Start:
mov bl, 0x0F ;Set text colour to 15
mov bh, 0x00 ;Set page to 0
mov cx, 0x001 ;Set number of characters to 1
xor dx, dx ;Set x and y to 0
mov ds, dx ;Allow for message loading
cld ;Allow for message loading
Print:
mov si, Msg ;Load the pointer Msg into si
Char:
mov ah, 0x02 ;Set the sub-function to 2
int 0x10 ;Call function 0x10 - position cursor
lodsb ;load the byte at si into al
mov ah, 0x09 ;Set the sub-function to 9
int 0x10 ;Call function 0x10 - print character
inc dl ;Advance the cursor
cmp dl, 80 ;If the cursor is past column 80
jne Skip ;Else jump to Skip
xor dl,dl ;reset the cursor's x value
inc dh ;move the cursor down a row
cmp dh, 25 ;If the cursor is past line 25
jne Skip ;Else jump to Skip
xor dh,dh ;move the cursor to the top row
Skip:
cmp si, EndMsg ;If the message is finished
jne Char ;Else print another character
ResetDisk:
mov ah, 0x00 ;Reset sub-function
mov dl, 0x00 ;Drive declaration
int 0x13 ;Disk function, sub 0 - Reset disk
jc ResetDisk ;If this fails, try again
ReadDisk:
mov bx, 0x8000 ;Where in RAM to drop the read data
mov es, bx
mov bx, 0x0000 ;RAM offset value
mov ah, 0x02 ;Set sub-function
mov al, 0x01 ;Set the number of sectors to read
mov ch, 0x00 ;Set the cylinder to read
mov cl, 0x02 ;Set the sector to start at (begins at 1, rest start at 0)
mov dh, 0x00 ;Set the drive head to read from
mov dl, 0x00 ;Set which drive to read from
int 0x13 ;Disk function, sub 2 - Read disk as described above
jc ReadDisk
AdvanceToSectorTwo:
jmp 0x8000:0x0000 ;Jump to the location of the second sector
times 0x0200 - 2 - ($ - $$) db 0 ;Fill the rest of the first sector up to byte 510
dw 0xAA55 ;Set bytes 511 and 512 to be the boot-disk signature
times 1474560 - ($ - $$) db 0 ;Fill up the rest of the floppy image as blank space
扇区2(0x0200-0x3FF):
org 0x8000
bits 16
Start:
mov bl, 0x0F ;Set text colour to 15
mov bh, 0x00 ;Set page to 0
mov cx, 0x001 ;Set number of characters to 1
mov dl, 23 ;Set column
mov dh, 0 ;Set Row
mov ds, dx ;Allow for message loading
cld ;Allow for message loading
Print:
mov si, Msg ;Load the pointer Msg into si
Char:
mov ah, 0x02 ;Set the sub-function to 2
int 0x10 ;Call function 0x10 - position cursor
lodsb ;load the byte at si into al
mov ah, 0x09 ;Set the sub-function to 9
int 0x10 ;Call function 0x10 - print character
inc dl ;Advance the cursor
cmp dl, 80 ;If the cursor is past column 80
jne Skip ;Else jump to Skip
xor dl,dl ;reset the cursor's x value
inc dh ;move the cursor down a row
cmp dh, 25 ;If the cursor is past line 25
jne Skip ;Else jump to Skip
xor dh,dh ;move the cursor to the top row
Skip:
cmp si, EndMsg ;If the message is finished
jne Char ;Else print another character
jmp Start ;Restart this part of the program
Msg: db "floppy sector 2 loaded!"
EndMsg:
很抱歉这太久了。再次,它打印第一个字符串就好了,但第二个它拒绝打印,它只是移动光标。任何建议都非常感谢。
答案 0 :(得分:0)
除了使用错误的ORG值之外,正如Jester在评论中指出的那样,您还要加载DS,其值为0023h,即光标的初始值。相反,您应该使用存储在CS中的值加载DS,这样您的第二个扇区就不会关心它加载到哪个网段。例如:
org 0
bits 16
Start:
mov bl, 0x0F ;Set text colour to 15
mov bh, 0x00 ;Set page to 0
mov cx, 0x001 ;Set number of characters to 1
mov dl, 23 ;Set column
mov dh, 0 ;Set Row
push cs
pop ds
cld ;Allow for message loading
...