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

标签 assembly x86 interrupt x86-16 dosbox

我无法让 MASM 接受写为 call 0f000h:1260h 的远程调用指令,可能是因为 this question 中提出的问题.

我决定使用 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 跟踪程序时,我注意到在执行 call 指令后出现“DB FE”。但是,在执行 int 1ch 时不会发生这种情况。 .这两种跳转到位置 f000:1260 的方法有什么区别?

enter image description here

我认为 DEBUG 没有将 0xfe (以及以下字节)识别为有效的操作码。我转储了位置 f000:1260 以查看那里有哪些字节。

enter image description here

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

这是 int 1ch 的 IVT 条目在位置 0000:0070。

enter image description here

更新

正如 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)

唯一的区别是 intFLAGS , 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

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

关于assembly - 在手动编码的远调用后定义出现在调试中的字节,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48652511/

相关文章:

c - 节目入口自认

assembly - 新的 X86_64 处理器寄存器的名称是什么?

c - Intel 指令的 LOCK 前缀。重点是什么?

microcontroller - 通过 8051 微 Controller 上的中断进行 UART 传输

c - 微 Controller 中的全局定时器时间中断

linux - 关于中断和中断处理的问题

c - 程序集中局部变量的大小

c - 构建交叉编译器的必要性

assembly - 在 x86 汇编中是否可以用 mul 乘以立即数?

c - 如何更改程序集中的指针值 (x86)