根据定义,是的。
软件需要一些执行环境,否则它只是存储在某个存储设备上的一组位。运行时环境有好几类,有时不同类型环境之间的区别很模糊。
一层是硬件提供的环境,包括指令集架构、设备提供的服务、BIOS等。
然后是操作系统提供的环境。操作系统以各种复杂程度工作,但通常充当运行程序和主机硬件之间的中介。一些操作系统非常薄,从某种意义上说,程序能够在没有操作系统中介的情况下做事。其他人阻止软件直接与硬件通信,因此程序必须发出请求(例如通过操作系统设施或服务),然后操作系统直接与硬件交互。
在另一个层面是与编程语言相关的指定环境。许多编程语言的语义是用在一些抽象机器上的执行来表示的。示例包括 C 和 C++,其中每个表达式、每个声明和每个语句在抽象机器上都有一组定义的效果。许多未定义行为的实例(如标准中规定的)相当于语言语句能够超出该抽象机器可接受范围的情况。
与以前的环境类型密切相关,有些语言与某种形式的库相关联。该标准库提供了使程序员的工作更轻松的设施。几乎所有中等高级语言都与库相关联 - C、C++、Java、Ada 等。其中许多功能可以在语言本身中实现,但其他一些需要主机系统的帮助(例如操作系统、硬件等),因此可以用另一种语言(例如汇编程序)实现。
下一级是运行时环境(例如 Java 虚拟机),程序(某种格式)在其中执行。这些程序(通常)只与那个运行时环境通信,而后者又从它所在的系统请求操作。有时程序可以直接与主机系统通信(通过称为 thunking、本机接口等的机制)。
还有一些程序可以即时解释代码(例如语言解释器),因此实际上,源代码本身就是程序,解释器从托管它的环境请求服务。
即使是用汇编编写的程序也可以在某些环境中运行。汇编被翻译成特定于某些主机环境(包括硬件,可能是操作系统,可能是操作系统托管的其他程序)的特定于机器的指令。
还有一些特殊类型的操作系统(例如管理程序)可以托管其他操作系统,并且通常允许多个操作系统在单个硬件平台上同时执行。当操作系统试图访问硬件时,调用会被管理程序拦截和调解,进而向主机硬件发出请求。
问题是,所有这些事情都涉及软件对其执行的环境做出一些假设。即使是用汇编程序编写的直接与硬件通信的软件也假设有一组硬件和一种与该硬件通信的方法。固件是一种假定它在某些设备(例如主板、内存控制器、硬盘控制器等)上运行的软件。