定义在手动编码的远调用之后出现在调试中的字节
Define byte appearing in debug after a manually encoded far call
我无法让 MASM 接受写成 call 0f000h:1260h
的远调用指令,可能是因为 .
中提出的问题
我决定使用 DB 将其手动编码到我的程序中,而不是乱搞神秘的 MASM 指令:
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
在使用 DEBUG.COM 跟踪程序时,我注意到 "DB FE" 在调用指令执行后出现。但是,执行 int 1ch
时不会发生这种情况。这两种跳转到位置f000:1260的方法有什么区别?
我假设 DEBUG 没有将 0xfe(连同以下字节)识别为有效的操作码。我转储位置 f000:1260 以查看那里有哪些字节。
字节 0xfe 和其他一些字节确实存在。
我知道 0xcf 本身就是 IRET 的操作码(这是我期望找到的所有内容),那么这些其他字节是什么?
这是 int 1ch
在位置 0000:0070 的 IVT 条目。
更新
正如 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.
好像和执行完全一样:
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)
唯一的区别是 int
压入 FLAGS
、CS
和 IP
,以及清除 IF 和 TF。该程序返回到 IRET(位于 f000:1264 位置),它会撤消所有这些操作。
"DB FE" 仍然出现在 DEBUG 中。我认为回调仅由 0xfe 和 0x38 的组合触发。它首先尝试执行 0xfe,在这种情况下,它不是有效操作码的一部分并且什么都不做(0xfe 是 inc
操作码的一部分,后跟有效字节),然后在遇到以下 0x38 时发生回调。
0xFE 0x38
不是真正的 Intel x86 处理器上定义的前缀 and/or 指令。在 DOSBox 中,序列 0xFE 0x38
是一个特殊的 4 字节 instruction.The 剩下的两个字节组成一个 16 位值,用作 DOSBox 回调索引号。在这种情况下,索引是 0x0013
.
这实际上是调用 DOSBox 本身来执行请求的任务。 DOSBox 将做任何它需要的处理,设置模拟器内部的寄存器,然后 returns。下一条指令是 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
此代码设置 DOSBox 回调,其中回调后需要 IRET
。
我无法让 MASM 接受写成 call 0f000h:1260h
的远调用指令,可能是因为
我决定使用 DB 将其手动编码到我的程序中,而不是乱搞神秘的 MASM 指令:
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
在使用 DEBUG.COM 跟踪程序时,我注意到 "DB FE" 在调用指令执行后出现。但是,执行 int 1ch
时不会发生这种情况。这两种跳转到位置f000:1260的方法有什么区别?
我假设 DEBUG 没有将 0xfe(连同以下字节)识别为有效的操作码。我转储位置 f000:1260 以查看那里有哪些字节。
字节 0xfe 和其他一些字节确实存在。 我知道 0xcf 本身就是 IRET 的操作码(这是我期望找到的所有内容),那么这些其他字节是什么?
这是 int 1ch
在位置 0000:0070 的 IVT 条目。
更新
正如 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.
好像和执行完全一样:
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)
唯一的区别是 int
压入 FLAGS
、CS
和 IP
,以及清除 IF 和 TF。该程序返回到 IRET(位于 f000:1264 位置),它会撤消所有这些操作。
"DB FE" 仍然出现在 DEBUG 中。我认为回调仅由 0xfe 和 0x38 的组合触发。它首先尝试执行 0xfe,在这种情况下,它不是有效操作码的一部分并且什么都不做(0xfe 是 inc
操作码的一部分,后跟有效字节),然后在遇到以下 0x38 时发生回调。
0xFE 0x38
不是真正的 Intel x86 处理器上定义的前缀 and/or 指令。在 DOSBox 中,序列 0xFE 0x38
是一个特殊的 4 字节 instruction.The 剩下的两个字节组成一个 16 位值,用作 DOSBox 回调索引号。在这种情况下,索引是 0x0013
.
这实际上是调用 DOSBox 本身来执行请求的任务。 DOSBox 将做任何它需要的处理,设置模拟器内部的寄存器,然后 returns。下一条指令是 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
此代码设置 DOSBox 回调,其中回调后需要 IRET
。