如何在x86仿真器中测试CPU异常?

如何在x86仿真器中测试CPU异常?,x86,emulation,X86,Emulation,我们正在编写一个专门的仿真器来模拟x86程序,并通过将其效果与实际情况进行比较来对指令进行单元测试。它是通过在调试器中设置断点来完成的,然后检查寄存器、标志和各种内存地址,看它们在给定点是否设置为与仿真器中相同的值 它可以很好地测试正常操作 但是我们如何对可能出现的CPU异常进行单元测试呢?例如,分段故障、零除法等? 使用普通的用户模式调试器是否可以获得异常中断号或类似的数字?如果我正确地假设您正在构建用户模式仿真器,那么您必须自己实现异常处理。根据手册,当处理器响应中断或异常时,它会停止当前任

我们正在编写一个专门的仿真器来模拟x86程序,并通过将其效果与实际情况进行比较来对指令进行单元测试。它是通过在调试器中设置断点来完成的,然后检查寄存器、标志和各种内存地址,看它们在给定点是否设置为与仿真器中相同的值

它可以很好地测试正常操作

但是我们如何对可能出现的CPU异常进行单元测试呢?例如,分段故障、零除法等?
使用普通的用户模式调试器是否可以获得异常中断号或类似的数字?

如果我正确地假设您正在构建用户模式仿真器,那么您必须自己实现异常处理。根据手册,当处理器响应中断或异常时,它会停止当前任务的执行,并切换到IDT中针对该异常情况安装的处理程序(有些异常,如SMI)。应用程序可以访问这些处理程序,但我不确定这是否对您有用。此外,请记住,某些中断/异常可能会保存相关状态(请参阅说明参考手册)


无论如何,您可以安装处理程序(在仿真CPU中)来跟踪异常和发生时的状态,以便对它们进行单元测试。

如果我正确地假设您正在构建用户模式仿真器,那么您必须自己实现异常处理。根据手册,当处理器响应中断或异常时,它会停止当前任务的执行,并切换到IDT中针对该异常情况安装的处理程序(有些异常,如SMI)。应用程序可以访问这些处理程序,但我不确定这是否对您有用。此外,请记住,某些中断/异常可能会保存相关状态(请参阅说明参考手册)


无论如何,您可以安装处理程序(在模拟CPU中)来跟踪异常和发生时的状态,以便对它们进行单元测试。

不,我不这么认为。考虑一个内存页映射到磁盘。当您访问它时,会生成一个页面错误,内核会截取它,从磁盘读回页面,然后重新启动执行,就好像什么都没发生一样


因此,真正的问题是,您无法在用户模式下验证退出用户模式的指令的行为。事实上,这同样适用于
系统调用

不,我不这么认为。考虑一个内存页映射到磁盘。当您访问它时,会生成一个页面错误,内核会截取它,从磁盘读回页面,然后重新启动执行,就好像什么都没发生一样


因此,真正的问题是,您无法在用户模式下验证退出用户模式的指令的行为。事实上,这同样适用于
系统调用

,在模拟器中实现异常处理程序是比较容易的部分。问题是我想通过将模拟器与实际CPU进行比较来验证它的正确性。例如,我除以零(整数除法),我可以在用户模式下为INT 0安装处理程序吗?因此,我可以在调试器中验证它是否真的像我预期的那样执行,并将其与仿真器进行比较。不,您不能在用户模式下安装异常处理程序。您必须修改并重新编译内核。不过,您仍然可以根据x86规范验证仿真器。在仿真器中实现异常处理程序是比较容易的部分。问题是我想通过将模拟器与实际CPU进行比较来验证它的正确性。例如,我除以零(整数除法),我可以在用户模式下为INT 0安装处理程序吗?因此,我可以在调试器中验证它是否真的像我预期的那样执行,并将其与仿真器进行比较。不,您不能在用户模式下安装异常处理程序。您必须修改并重新编译内核。不过,您仍然可以根据x86规范验证仿真器。这是否意味着,在用户模式下观察到的行为在很大程度上取决于操作系统和操作系统版本?这是否意味着不能简单地测试INT 0处理程序在被零除时是否真的被调用?那么这是否意味着,在用户模式下观察到的行为在很大程度上取决于操作系统和操作系统版本?这是否意味着不能简单地测试INT0处理程序在被零除时是否真的被调用?