我一直在搞乱多阶段引导程序,除了最后一部分外,我已经完成了所有代码的工作: The Jump 。我之前已经解决了这个代码,但我想通过替换这一行来使其更加模块化:
jmp 0x7E0:0
有了这个:
jmp far [Stage2Read + SectorReadParam.bufoff]
而不是代码加载的硬编码,我想间接跳转到它。这是我的其余代码:
; This is stage 1 of a multi-stage bootloader
bits 16
org 0x7C00
jmp 0:boot_main
%include "io16.inc"
boot_main:
; setup the new stack
cli
mov ax, 0x100
mov ss, ax
mov bp, 0x4000
mov sp, bp
sti
; Setup data segment
xor ax, ax
mov ds, ax
; Save which drive we booted from
mov [Stage2Read + SectorReadParam.drive], dl
; Home-made BIOS wrapper to read sectors into memory
mov si, Stage2Read
call ReadSectors
; Change to new data segment
mov ax, [Stage2Read + SectorReadParam.bufseg]
mov ds, ax
;jmp 0x7E0:0 ; THIS WORKS
jmp far [Stage2Read + SectorReadParam.bufoff] ; BUT THIS DOES NOT
; Used as the parameters for ReadSectors
Stage2Read: ISTRUC SectorReadParam
AT SectorReadParam.bufoff, dd 0
AT SectorReadParam.bufseg, dw 0x07E0
AT SectorReadParam.numsecs, db 1
AT SectorReadParam.track, db 0
AT SectorReadParam.sector, db 2
AT SectorReadParam.head, db 0
AT SectorReadParam.drive, db 0 ; needs to be initialized!
IEND
; Ending
times 510-($-$$) db 0
dw 0xAA55
请记住,除了间接远程跳转之外,所有这些代码都已经过测试和工作。这就是我需要让它发挥作用。我想知道是否可能隐含的间接远程跳转使用例如ds
,以便地址Stage2Read + SectorReadParam.bufoff
不正确。这真是让我烦恼,因为它看起来很简单。我想帮忙!
答案 0 :(得分:1)
您希望jmp far
从Stage2Read + SectorReadParam.bufoff
读取目标地址,0x0000:Stage2Read + SectorReadParam.bufoff
(ds
= 0x0000)。
但是,在跳转之前,ds
设置为0x07e0,因此在我看来,您的代码正在从0x07e0:Stage2Read + SectorReadParam.bufoff
读取其目标地址。
答案 1 :(得分:1)
您的原始代码中有几个错误。第一个是使用 DD (32位 DWORD )而不是16位 WORD 进行偏移的事实。这一行:
AT SectorReadParam.bufoff, dd 0
应该是:
AT SectorReadParam.bufoff, dw 0
默认情况下为 FAR JMP 指定内存操作数时(在您的情况下),它相对于 DS (数据段)。在 FAR JMP 之前,将 DS 设置为新值,因此 JMP 内存操作数将从错误的段读取内存地址(0x07e0而不是of 0x0000)。
您可以在 JMP 之后设置 DS ,或者您可以将内存操作数更改为相对于 CS (仍然是细分)使用数据)使用覆盖。它看起来像这样:
jmp far [CS:Stage2Read + SectorReadParam.bufoff]