【发布时间】:2021-11-03 04:03:38
【问题描述】:
我尝试制作自定义操作系统只是为了好玩,但遇到了一个问题,即我的print_str 代码在从引导加载程序加载到内核后无法工作。没有编译器警告,我可以打印字符。而不是打印我想要的内容,而是显示大约两个或三个随机字符。
引导加载程序:
[ORG 0x7c00]
bits 16
boot_stuff:
mov [BOOT_DRIVE], dl ; store boot drive for later use because the BIOS stores the boot drive in dl
mov bp, 0x8000 ; set stack
mov sp, bp ; out of the way at 0x8000
mov bx, 0x9000 ; Load 5 sectors to 0x0000(ES):0x9000(BX)
mov dh, 1 ; from the boot disk.
mov dl, [BOOT_DRIVE]
call disk_load
mov si, msg
call print_str
jmp 0x0000:0x9000
hang:
jmp hang
define_stuff:
print_str:
lodsb
mov ah, 0x0E
cmp al, 0
je done
int 0x10
jmp print_str
done:
ret
disk_load:
; load DH sectors to ES:BX from drive DL
push dx ; Store DX on stack so later we can recall how many sectors were requested to be read even if it is altered
mov ah, 0x02 ; BIOS read sector function
mov al, dh ; Read DH sectors
mov ch, 0x00 ; Select cylinder 0
mov dh, 0x00 ; Select head 0
mov cl, 0x02 ; Start reading from second sector (i.e. after the boot sector)
int 0x13 ; BIOS Interrupt
jc disk_error ; jump if carry flag set
pop dx ; Restore DX
cmp dh, al ; if AL (sectors read) != DH (sectors expected)
jne disk_error
ret
disk_error:
mov si, disk_error_msg
call print_str
jmp $
data_stuff:
BOOT_DRIVE db 0
msg db 'Booted', 0
nmsg db 'yonked', 0
disk_error_msg db 'DISK ERROR', 0
times 510-($-$$) db 0
dw 0xaa55
内核:
bits 16
entry:
mov ah, 0x0700
int 0x10
mov si, msg
call print_str
hang:
jmp hang
print_str:
lodsb
mov ah, 0x0E
cmp al, 0
je done
int 0x10
jmp print_str
done:
ret
data:
msg db 'Booted', 0
【问题讨论】:
-
LODSB/LODSW/LODSD从地址 (E)DS:(E)SI 加载 BYTE/WORD/DWORD。您是否将段寄存器 (E)DS 设置为有效值?注意:(段)寄存器(CS除外)的值在启动后未定义。 -
我将 SI 设置为 msg,即使我将 DS 设置为 0x0000,这应该与 ES 相同,即内核所在的段不起作用
-
nvm 我想通了
-
@zx485:连CS都不能保证,可能是0也可能是7C0。 Michael Petch's tips。此外,段寄存器没有更广泛的版本,它总是 DS,没有 x86 有 EDS。 felixcloutier.com/x86/lods:lodsb:lodsw:lodsd:lodsq。在非真实模式中,它是 GDT / LDT 条目的 选择器,因此它仍然不需要更宽。
-
在期望
lodsb朝着“更高的地址”方向工作之前,还应该确保方向标志是明确的(使用cld指令)。
标签: assembly nasm bootloader osdev