在手动编码的远程调用之后定义在调试中出现的字节

My *_*ug. 8 x86 assembly interrupt dosbox x86-16

我无法让MASM接受写成的远程调用指令call 0f000h:1260h,可能是因为这个问题带来的问题.

我没有乱用神秘的MASM指令,而是决定使用DB手动将其编码到我的程序中,如下所示:

pushf                      ;IRET will be executed, push flags.
db 9ah,60h,12h,0,0f0h      ;call location f000:1260.
                           ;Location pointed to by int 1c (System timer tick)
                           ;BIOS defaults it to a dummy IRET
Run Code Online (Sandbox Code Playgroud)

在使用DEBUG.COM跟踪程序时,我注意到在执行调用指令后出现"DB FE".但是,执行时不会发生这种情况int 1ch.跳转到位置f000:1260的这两种方法有什么区别?

在此输入图像描述

我假设DEBUG没有将0xfe(以及后面的字节)识别为有效的操作码.我倾倒了位置f000:1260以查看哪些字节存在.

在此输入图像描述

确实存在字节0xfe以及其他一些字节.我知道0xcf本身就是IRET的操作码(这是我期望找到的所有),那么这些其他字节是什么?

这是int 1ch位于0000:0070 的IVT条目.

在此输入图像描述

UPDATE

正如Michael Petch在他的回答中所说,奇怪的字节构成了DOSBox的回调机制.我很想知道如果我试图在我的主程序中执行这个回调会发生什么.

执行:

xor ah, ah                 ;select set video mode function
mov al, 13h                ;320x200 256 colors
db 0feh,38h,18h,00h        ;set video mode DOSBox callback.
                           ;Nothing pushed to stack.
Run Code Online (Sandbox Code Playgroud)

似乎与执行完全相同:

xor ah, ah                 ;select set video mode function
mov al, 13h                ;320x200 256 colors
int 10h                    ;set video mode.
                           ;Three registers pushed, FLAGS altered (by INT)
                           ;callback occurs, registers popped (by IRET)
Run Code Online (Sandbox Code Playgroud)

唯一的区别是int推动FLAGS,CSIP,以及清除IF和TF.程序返回到IRET(位置f000:1264),撤消所有这些.

"DB FE"仍出现在DEBUG中.我认为回调只是由0xfe和0x38的组合触发.它首先尝试执行0xfe,在这种情况下,它不是有效操作码的一部分,什么也不做(0xfe是inc后跟有效字节的操作码的一部分),然后在遇到以下0x38时发生回调.

Mic*_*tch 9

0xFE 0x38不是真正的Intel x86处理器上定义的前缀和/或指令.在DOSBox中,序列0xFE 0x38是一个特殊的4字节指令.剩下的两个字节组成一个16位值,充当DOSBox回调索引号.在这种情况下,索引是0x0013.

这实际上是调用DOSBox本身来执行所请求的任务.DOSBox将执行它需要的任何处理,在模拟器中设置寄存器然后返回.下一条指令是IRET(0xCF).这将结束中断并在中断调用之前继续处理指令.

我在查看DOSBox代码时发现了这一点.特别是功能CALLBACK_SetupExtra:

case CB_IRET:
    if (use_cb) {
        phys_writeb(physAddress+0x00,(Bit8u)0xFE);  //GRP 4
        phys_writeb(physAddress+0x01,(Bit8u)0x38);  //Extra Callback instruction
        phys_writew(physAddress+0x02,(Bit16u)callback);     //The immediate word
        physAddress+=4;
    }
    phys_writeb(physAddress+0x00,(Bit8u)0xCF);      //An IRET Instruction
Run Code Online (Sandbox Code Playgroud)

此代码设置DOSBox回调,其中IRET回调后需要a.