5

不久前我决定开始学习汇编,所以我从 16 位汇编开始,使用 FASMW。然而,我最近得到了一台运行 Windows 7 64 位的真正新计算机,现在程序组装的已编译 .COM 文件不再工作了。他们给出一条错误消息,指出 .COM 与 64 位 Windows 不兼容。32 位程序集仍然可以工作,但我宁愿从 16 开始,然后逐步提高... 是否可以在 Windows 7 上运行 16 位程序?还是有特定的方法来编译它们?还是我应该放弃并跳到 32 位?

4

3 回答 3

8

不能使用 16 位程序集的原因是16 位子系统 已从所有 64 位版本的 Windows 中删除。

解决这个问题的唯一方法是安装 DOSBox 之类的东西,或 VirtualBox 之类的虚拟机包,然后将 FreeDOS 安装到其中。这样,无论如何,您都会获得真正的 DOS。(NTVDM 不是真正的 DOS

就个人而言,我会鼓励为 DOS 编写 16 位程序集吗?不,我会使用 32 位甚至 64 位程序集——原因是针对不同的操作系统(称为 ABI)有一组不同的函数调用。因此,64 位 Linux 应用程序的 ABI 与 32 位应用程序不同。不确定Windows是否是这种情况。但是,我保证中断的含义可能不同。

此外,对于 16 位汇编,您需要考虑各种事情,例如使用中的内存模型。我可能是错的,但我相信 DOS 会给你 64K 内存来玩“就是这样”。一切,你的整个堆和堆栈以及代码都必须适合这个空间,据我所知,这让你想知道任何东西是如何工作的,真的。

于 2010-09-01T17:55:07.063 回答
7

我的建议是只编写 32 位代码。虽然最初似乎学习如何编写 16 位代码,然后“毕业”到 32 位代码是有意义的,但实际上我想说的恰恰相反:编写 32 位代码实际上更容易因为相当多的任意架构约束(例如,关于可以用作基址寄存器的内容)基本上在 32 位代码中消失了。

就此而言,我认为是否有真正的理由编写 16 位 x86 代码存在重大问题。对于大多数实际用途,它是一个死平台——对于台式机来说,它已经过时了,而对于嵌入式机器,你更有可能看到像 ARM 或 Microchip PIC 这样的东西。除非您有一个特定的目标并且确定它会是 16 位 x86,否则我可能会忘记它的存在,就像世界上大多数其他地方一样。

于 2010-09-01T18:00:28.010 回答
1

默认情况下,32 位 Windows 7 和更早版本包括/启用 NTVDM。在 32 位 Win8+ 上,您可以在 Windows Features 中启用它

在 64 位 Windows(或任何其他 64 位操作系统)上,您需要一个模拟器或完全虚拟化。

长模式的内核不能使用 vm86 模式来提供虚拟的 8086 实模式环境。这是 AMD64 / x86-64 架构的限制。

在运行 64 位内核的情况下,您的 CPU 在 16 位模式下本机运行的唯一方法是 16 位保护模式(是的,这存在;不,没有人使用它,AFAIK 主流操作系统不提供一种方法用它)。或者内核将 CPU 从长模式切换回传统模式,但 64 位内核不这样做。

但实际上,通过硬件虚拟化(VirtualBox、Hyper-V 或任何使用 Intel VT-x 或 AMD SVM),64 位内核可以成为整个虚拟机的管理程序,无论该 VM 是否在 16 位实模式下运行或运行 32 位操作系统(如 Windows 98 或 2000),后者又可以使用 vm86 模式运行 16 位实模式可执行文件。

特别是在 64 位内核上,完全模拟 16 位 PC(就像 DOSBOX 一样)通常更容易,而不是使用硬件虚拟化来本地运行正常指令,但会捕获直接硬件访问(in/ out,加载/存储到 VGA 内存等)以及int进行 DOS 系统调用/BIOS 调用/其他的指令。

于 2018-05-02T00:01:52.537 回答