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,CS和IP,以及清除IF和TF.程序返回到IRET(位置f000:1264),撤消所有这些.
"DB FE"仍出现在DEBUG中.我认为回调只是由0xfe和0x38的组合触发.它首先尝试执行0xfe,在这种情况下,它不是有效操作码的一部分,什么也不做(0xfe是inc后跟有效字节的操作码的一部分),然后在遇到以下0x38时发生回调.
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.