不久前我决定开始学习汇编,所以我从16位汇编开始,使用FASM。然而,我最近得到了一台真正的新电脑运行Windows 7 64位,现在没有一个编译的.COM文件,该程序汇编任何工作了。他们给予了一个错误消息,说.COM是不兼容的64位然而。32-位程序集仍然工作,但我宁愿从16开始,然后逐步增加...在windows7上运行一个16位程序是可能的吗?或者有一个特定的方法来编译它们?或者我应该给予并跳到32位来代替?
qfe3c7zg1#
您不能使用16位程序集的原因是因为所有64位版本的Windows中的16-bit subsystemhas been removed。解决这个问题的唯一方法是安装类似DOSBox的东西,或者安装一个虚拟机包,比如VirtualBox,然后再安装FreeDOS。这样,你就得到了真正的DOS。(NTVDM不是真正的DOS。)就我个人而言,我会鼓励为DOS编写16位汇编吗?不,我会使用32位甚至64位汇编,原因是不同的操作系统有不同的函数调用集(称为ABI)。因此,64位Linux应用程序的ABI与32位应用程序不同。我不确定Windows是否如此。不过,我保证中断的含义可能是不同的。而且,你有很多事情要考虑16位汇编,比如使用的内存模型。我可能是错的,但是我相信DOS给你64K内存来玩“就是这样”。所有的东西,你的整个堆和堆栈沿着代码都必须适合这个空间,正如我所理解的,这让你想知道任何东西是如何工作的,真的。
ldxq2e6h2#
我的建议是只写32位代码。虽然最初看起来学习如何写16位代码,然后“毕业”到32位代码是有意义的,但我想说的是,事实恰恰相反:编写32位代码实际上更容易,因为相当多的任意体系结构约束(例如,关于什么可以用作基址寄存器)基本上在32位代码中消失了。就此而言,我认为是否有真实的的理由编写16位x86代码是一个实质性的问题。对于大多数实际用途来说,它是一个死平台--对于台式机来说,它已经“严重”过时了,对于嵌入式机器来说,您更可能看到ARM或Microchip PIC之类的产品。除非您心中有一个特定的目标,并且确信它将是一个16位x86,我可能会忘记它的存在,就像世界上其他大多数人一样。
umuewwlo3#
32-位Windows 7和更早版本默认包含/启用NTVDM。在32位Win8+上,您可以在Windows功能中启用它。在64位Windows(或任何其他64位操作系统)上,您需要一个模拟器或完全虚拟化。长模式的内核不能使用vm 86模式来提供虚拟的8086实模式环境。这是AMD 64/ x86-64架构的一个限制。在运行64位内核的情况下,CPU在16位模式下本地运行的唯一方法是16位 protected 模式(是的,这是存在的;不,没有人使用它,AFAIK主流操作系统也没有提供使用它的方法)。或者内核将CPU从长模式切换回传统模式,但64位内核不会这样做。但实际上,通过硬件虚拟化(VirtualBox、Hyper-V或任何使用英特尔VT-x或AMD SVM的虚拟机),64位内核可以成为整个虚拟机的虚拟机管理程序,无论该虚拟机是在16位真实的模式下运行,还是在32位操作系统(如Windows 98或2000)下运行,后者可以使用vm 86模式运行16位实模式可执行文件。特别是在64位内核上,通常更容易完全模拟16位PC(如DOSBOX),而不是使用硬件虚拟化来本地运行正常指令,但会捕获直接硬件访问(in/out、加载/存储到VGA内存等)和进行DOS系统调用/ BIOS调用/其他操作的int指令。
in
out
int
3条答案
按热度按时间qfe3c7zg1#
您不能使用16位程序集的原因是因为所有64位版本的Windows中的16-bit subsystemhas been removed。
解决这个问题的唯一方法是安装类似DOSBox的东西,或者安装一个虚拟机包,比如VirtualBox,然后再安装FreeDOS。这样,你就得到了真正的DOS。(NTVDM不是真正的DOS。)
就我个人而言,我会鼓励为DOS编写16位汇编吗?不,我会使用32位甚至64位汇编,原因是不同的操作系统有不同的函数调用集(称为ABI)。因此,64位Linux应用程序的ABI与32位应用程序不同。我不确定Windows是否如此。不过,我保证中断的含义可能是不同的。
而且,你有很多事情要考虑16位汇编,比如使用的内存模型。我可能是错的,但是我相信DOS给你64K内存来玩“就是这样”。所有的东西,你的整个堆和堆栈沿着代码都必须适合这个空间,正如我所理解的,这让你想知道任何东西是如何工作的,真的。
ldxq2e6h2#
我的建议是只写32位代码。虽然最初看起来学习如何写16位代码,然后“毕业”到32位代码是有意义的,但我想说的是,事实恰恰相反:编写32位代码实际上更容易,因为相当多的任意体系结构约束(例如,关于什么可以用作基址寄存器)基本上在32位代码中消失了。
就此而言,我认为是否有真实的的理由编写16位x86代码是一个实质性的问题。对于大多数实际用途来说,它是一个死平台--对于台式机来说,它已经“严重”过时了,对于嵌入式机器来说,您更可能看到ARM或Microchip PIC之类的产品。除非您心中有一个特定的目标,并且确信它将是一个16位x86,我可能会忘记它的存在,就像世界上其他大多数人一样。
umuewwlo3#
32-位Windows 7和更早版本默认包含/启用NTVDM。在32位Win8+上,您可以在Windows功能中启用它。
在64位Windows(或任何其他64位操作系统)上,您需要一个模拟器或完全虚拟化。
长模式的内核不能使用vm 86模式来提供虚拟的8086实模式环境。这是AMD 64/ x86-64架构的一个限制。
在运行64位内核的情况下,CPU在16位模式下本地运行的唯一方法是16位 protected 模式(是的,这是存在的;不,没有人使用它,AFAIK主流操作系统也没有提供使用它的方法)。或者内核将CPU从长模式切换回传统模式,但64位内核不会这样做。
但实际上,通过硬件虚拟化(VirtualBox、Hyper-V或任何使用英特尔VT-x或AMD SVM的虚拟机),64位内核可以成为整个虚拟机的虚拟机管理程序,无论该虚拟机是在16位真实的模式下运行,还是在32位操作系统(如Windows 98或2000)下运行,后者可以使用vm 86模式运行16位实模式可执行文件。
特别是在64位内核上,通常更容易完全模拟16位PC(如DOSBOX),而不是使用硬件虚拟化来本地运行正常指令,但会捕获直接硬件访问(
in
/out
、加载/存储到VGA内存等)和进行DOS系统调用/ BIOS调用/其他操作的int
指令。