是否可以在支持Intel IA-32e模式的操作系统中运行16位代码?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了是否可以在支持Intel IA-32e模式的操作系统中运行16位代码?相关的知识,希望对你有一定的参考价值。

在Intel 64和IA-32架构手册第3A卷第9章处理器管理和初始化中,我发现了以下内容:

在代码段的基础上选择兼容模式执行。此模式允许旧版应用程序与以64位模式运行的64位应用程序共存。在IA-32e模式下运行的操作系统可以通过将其代码段描述符的CS.L位清除为0来执行现有的16位和32位应用程序。

这是否意味着传统的16位和32位应用程序可以与在IA-32e模式下运行的操作系统上的64位应用程序共存。

但据我所知,64位操作系统通常不支持传统的16位代码。如果支持,我该如何启动16位应用程序?

答案

Windows 64位不支持16位应用程序的原因不是因为64位模式无法运行16位指令。

主要原因是句柄在64位Windows上有32位有效位。因此,句柄不能被截断并传递给16位应用程序而不会丢失数据。

http://msdn.microsoft.com/en-us/library/aa384249%28VS.85%29.aspx

另一答案

32位应用程序由64位架构支持,因此它们可以共存,对于16位应用程序,您需要一些工具来模拟寻址空间,例如Windows上的dosbox

另一答案

在64位内核下,可以使用16位保护模式用户空间,但不能使用虚拟8086模式。

大多数16位软件是为DOS编写的,并且希望以实模式运行。 vm86(virtual-8086)模式基本上是实模式的硬件虚拟化,允许访客使用cli / sti,而不会影响EFLAGS中的实际IF位。

在16位保护模式下,cli仅在IO权限级别为0(如环0)时才有效,并且它将禁用该实际CPU内核上的中断,而不仅仅是在16位模拟环境中。因此,在现代操作系统下运行16位DOS程序没有用。

所以,是的,你可以在64位内核下运行16位用户空间代码,但只能在没有人使用的16位保护模式下运行(AFAIK)。我不认为Linux原生支持16位进程,尽管你可以使用modify_ldt系统调用和jmp far创建一个自定义的16位代码段。


可能有可能构建一个软件虚拟化系统,该系统使用16位保护模式来运行16位DOS客户机,当客户机运行像cli这样的指令时,会捕获内核/虚拟机管理程序。 @LưuVĩnhPhúc的回答是MS没有尝试这样做的一个原因。

但是,x86的软件虚拟化并非易事,因为您需要模拟的一些指令(如pushf)实际上并不存在陷阱。客人可能会注意到(或因为)因为pushf结果中的中断启用标志(IF)与它刚刚运行的cli不匹配。


即使是最慢的x86-64 CPU也足够快,可以运行像DOSBOX这样的软件,完全模拟具有可直接访问的旧硬件的x86 PC,因此对本机运行16位代码或需求量不大的需求不大以一种看起来“本机”的方式运行它,即能够在主OS下启动其他程序而不是在模拟环境中启动。

显然there was a Linux patch (last updated in 2008)在64位内核下运行vm86,可能暂时将内核切换到保护模式?或者只是运行软件模拟。

以上是关于是否可以在支持Intel IA-32e模式的操作系统中运行16位代码?的主要内容,如果未能解决你的问题,请参考以下文章

将 GCC 的 __builtin_ia32_pshufd 和 __v4si 模式转换为可移植的内在模式?

Intel64和IA-32架构软件开发者手册第1卷:基本架构

cmp 不工作 - Intel x86 (IA32) 程序集

IA-32e模式下的异常处理

IA32的三种地址

Intel 64 and IA-32 Architectures Instruction Format 指令格式