mov ax,0x4D8C ; segment selector
mov es,ax
int 0x3C ; call x87 emulator??
fld dword ptr [<some address>]
sub sp,8
int 0x39 ; call x87 emulator??
...等。粗略的搜索引擎搜索强烈暗示
int
指令正在调用x87仿真库。当存在x87时,它可以让协处理器执行指令,但是当x87不存在时,模拟器可以仿真。我非常熟悉如何通过移位和诸如此类来实现FPU操作。我想了解更多有关仿真器的这些调用的协议。我一直找不到文档。也许RE社区的成员之一呢?
#1 楼
没有什么比在stackexchange上提出问题更要被找到答案(或者至少是答案的一部分)而感到羞耻的了。找到以下源文件后,它开始变得有意义:https://github.com/alexhenrie/wine/blob/master/dlls/krnl386.exe16/fpu.c
在没有错误指令陷阱的旧8086机器上,过去的长辈提出了一种仿真策略。所有x87指令都在
D8
-DF
范围内(8个可能的值),其后是modrm和其他优缺点。如果在指令前加上FWAIT
(操作码9B
),则可以保证在modrm字节之前始终有两个字节的代码,看起来像9B Dx
。但是,编译器将发出CD xx
,而不是发出这两个字节,其中xx范围是34
-3B
(8个可能的值)。众所周知,CD是x86 int
指令的编码。当CPU执行
int
指令并到达34
-3B
的处理程序时,它将转到中断处理程序。如果没有可用的x87协处理器,则处理程序将模拟浮点指令,并在内存中保持协处理器状态。但是,如果存在x87协处理器,则处理程序将窥视返回堆栈以查看int
指令的位置,并使用与9B Dx
字节序列相对应的相应CD 3x
字节序列覆盖该指令。然后,它将控制权返回给修补的指令,以便执行该指令。现在已经对其进行了修补,该指令是一条实际的FPU指令,并且该指令的未来执行将不再需要通过仿真器进行漫长的绕行。如何处理中断
3E
的文档为仍然不行。但是,暂时,我有足够的信息来在Reko反编译器中实现x87仿真支持。评论
自我答案不会(不应)让我们感到羞耻-学习是一件好事:P
–猫
16-3-22在15:45
太酷了-我记得当时回想起二进制文件中的中断调用-十几岁的我无法解释为什么协处理器操作码从未出现过。
–jsbueno
16 Mar 23 '16 at 0:59
你知道,我实际上记得那件事。不是细节,只是它使用INT代替了fpu操作码。
–JDługosz
16-3-23在3:36
现在,该功能已在Reko中实现,并且可以正常工作。
– JohnKällén
16 Mar 23 '16 at 7:52
评论
我会使用位移和遮罩进行成像以提取指数和尾数,然后使用定点数学来获取结果我了解如何使用整数寄存器执行FP数学。我想知道的是用于调用FP仿真的绑定机制-那些int指令期望的寄存器。
转到ralf browns主页并下载软件包,其中一个软件包将包含int.com,您可以使用它们进行int调用,例如int.com 0x3c -ax 0xxx -bx 0xyyyy cs.cmu.edu/~ralf/files.html今天的日期INT.COM 0x21 -ah 0x2a AX = 2A00 BX = 0000 CX = 0000 DX = 0000 SI = 0000 DI = 0000 BP = FFAC SP = FFA0 CS = 0000 DS = 0000 ES = 0000 SS = 0000 CPU标志:0n00oditsz0a0p1c INT :0x21 AX = 2A02 BX = 0000 CX = 07E0 DX = 0316 SI = 0000 DI = 0000 BP = FFAC SP = FFA0 CS = 0000 DS = 0000 ES = 0000 SS = 0000 CPU标志:0N11odItSz0A0P1C DOSERR:0057(87)
这可能会有所帮助:delphigroups.info/2/d7/740.html
@JasonGeffner:谢谢,这正是我一直在寻找的链接。看来我的Ralf中断清单副本过时。