x86 NASM实模式下的间接跳远 [英] x86 NASM Indirect Far Jump In Real Mode

查看:83
本文介绍了x86 NASM实模式下的间接跳远的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在搞一个多阶段的引导程序,除了后半段 Jump 之外,我所有的代码都可以使用.我之前已经获得了这段代码,但是我想通过替换以下行使其更加模块化:

I have been messing around with a multi-stage bootloader and I have got all of my code to work, except for the last part: The Jump. I have gotten this code to work out before now but I wanted to make it more modular by replacing this line:

jmp 0x7E0:0

有了这个:

jmp far [Stage2Read + SectorReadParam.bufoff]

我不是要在其中加载代码的硬编码,而是要进行间接跳转.这是我其余的代码:

Instead of hard coding where the code will load in, I wanted to do an indirect jump to it. Here's the rest of my code:

; 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 会是不正确的.这真的让我烦恼,因为它是如此简单.我需要帮助!

Remember all this code has been tested and works except for the indirect far jump to work. That's all I need to get this to work. I was wondering if maybe the indirect far jump implicitly is using for example ds so that the address Stage2Read + SectorReadParam.bufoff would be incorrect. This is really bugging me because it is so seemingly simple. I would like help!

推荐答案

您的原始代码中有几个错误.首先是使用 DD (32位 DWORD )而不是16位 WORD 的偏移量.这行:

You had a couple of bugs in your original code. The first was the fact that you had the offset using a DD (32-bit DWORD) instead of a 16-bit WORD. This line:

AT SectorReadParam.bufoff, dd 0

应该是:

AT SectorReadParam.bufoff, dw 0

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

When you specify the memory operand for the FAR JMP by default (in your case) it is relative to the DS (data segment). Before the FAR JMP you set DS to a new value, so the JMP memory operand will read the memory address from the wrong segment (0x07e0 instead of 0x0000).

您可以在 JMP 之后设置 DS ,也可以将内存操作数更改为相对于 CS 的内存(仍然是段使用数据).看起来可能像这样:

You can either set DS after you JMP or you can change the memory operand to be relative to CS (which is still the segment with the data) using an override. It could look like this:

jmp far [CS:Stage2Read + SectorReadParam.bufoff]

这篇关于x86 NASM实模式下的间接跳远的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆