Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/assembly/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Assembly 实模式下的x86 NASM间接跳远_Assembly_X86_Nasm_X86 16_Bootloader - Fatal编程技术网

Assembly 实模式下的x86 NASM间接跳远

Assembly 实模式下的x86 NASM间接跳远,assembly,x86,nasm,x86-16,bootloader,Assembly,X86,Nasm,X86 16,Bootloader,我一直在摆弄一个多级引导加载程序,我所有的代码都可以工作,除了最后一部分:跳转。我以前已经编写过这段代码,但我想通过替换这一行使其更加模块化: jmp 0x7E0:0 关于这一点: jmp far [Stage2Read + SectorReadParam.bufoff] 我想做一个间接的跳转到它,而不是硬编码,代码将加载到其中。以下是我的其余代码: ; This is stage 1 of a multi-stage bootloader bits 16

我一直在摆弄一个多级引导加载程序,我所有的代码都可以工作,除了最后一部分:跳转。我以前已经编写过这段代码,但我想通过替换这一行使其更加模块化:

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
就不正确了。这真的让我很烦,因为它看起来很简单。我想要帮助

您希望
jmp far
Stage2Read+SectorReadParam.bufoff
读取其目标地址,这实际上是
0x0000:Stage2Read+SectorReadParam.bufoff
ds
=0x0000)


但是,就在跳转之前,
ds
被设置为0x07e0,因此在我看来,您的代码正在从
0x07e0:Stage2Read+SectorReadParam.bufoff
读取其目标地址。您的原始代码中有几个错误。第一个事实是,偏移量使用DD(32位DWORD)而不是16位字。这一行:

AT SectorReadParam.bufoff, dd 0
应该是:

AT SectorReadParam.bufoff, dw 0
默认情况下(在本例中)为FAR JMP指定内存操作数时,它是相对于DS(数据段)的。在FAR JMP之前,您将DS设置为新值,因此JMP内存操作数将从错误的段(0x07e0而不是0x0000)读取内存地址

可以在JMP之后设置DS,也可以使用重写将内存操作数更改为相对于CS(它仍然是包含数据的段)。它可能是这样的:

jmp far [CS:Stage2Read + SectorReadParam.bufoff]

也许我看错了,但您在SectorReadParam.bufoff,dd 0上有
。即DD(32位值)设置为零。在我看来,
jmp far-dword[Stage2Read+SectorReadParam.bufoff]
将跳转到0x0000:0x0000?@MichaelPetch-Oops是的,这是一个bug,但仍然不起作用……我已经将DD/DW bug放回你的问题中,以保持我上面写的原始注释的相关性。因此它确实使用了一个隐式寄存器。。。谢谢