【问题标题】:Why doesn't lodsb work after bootloading into the kernel?为什么 lodsb 在引导加载到内核后不工作?
【发布时间】: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


【解决方案1】:

我需要做的只是[org 0x9000],因为我已将内核加载到 ES:0x9000

【讨论】:

  • 您很幸运,您的 BIOS 恰好设置 DS=0 以匹配您的 org,但不能保证这一点。 (或者 ES=DS 如果它们都非零,并且您只是在 0x9000 加上一些未知的 16 倍数覆盖内存。)以及写入DS:BOOT_DRIVE,无论发生在哪里。
猜你喜欢
  • 2018-03-26
  • 1970-01-01
  • 2020-09-10
  • 1970-01-01
  • 2015-11-13
  • 1970-01-01
  • 1970-01-01
  • 2019-10-24
  • 2016-02-09
相关资源
最近更新 更多