程序

来自智得网
跳转至: 导航、​ 搜索

简介

Java程序的编译和运行.png

程序有多个层次的概念,比如开发人员依据编程语言的语法实现的可以执行特定的功能的代码叫程序,代码通过编译之后运行物理设备上的进程也叫程序。

软件就是运行在一定硬件之上的程序,它可以完成预先设计好的指令。比如我们常用的微信、淘宝、视频播放器、浏览器都是软件,这些软件一般执行在我们熟悉的手机、电脑等硬件之上,除了这些常见的硬件平台之外,还有一些其他平台也可以运行软件,例如现在的摄像头、游戏机等。

程序在生命周期的不同阶段有不同的表现形式。在软件工作人员开发完成之后,一般而言,程序是可以阅读的符合一定语法规范的文本,这时候的程序是静态的,但是当程序在一定硬件上启动之后,程序根据外部输入或者自动执行特定的功能,此时的程序是动态的。

原理

JVM的JIT即时编译与解释混合执行的流程图

静态的程序一般采用C、C++、PHP、Python、Golang等语言编写。其中有一些语言是静态语言,静态语言是指其程序有固定的内存布局,通过编译和链接程序的地址空间都是明确的。动态语言是程序在运行的时候才能决定程序的内存布局。

因为静态语言的特性,静态语言在编写的时候,所有的变量需要有明确的类型,而且除了强制转换之外,类型不能发生变化,而动态语言可以在程序运行的时候才给变量赋值,所以动态语言不需要提前制定类型。

解释执行

解释执行需要解释器程序来运行程序,解释器执行程序分为下列过程:

  • 词法分析:扫描器(Scanner)将源代码分割成一系列的记号(Token),词法分析的工具有lex。
  • 语法分析:语法分析器将记号(Token)生成语法树(Syntax Tree),yacc是常用的语法分析工具。
  • 语义分析:分析语法树的语义,进行类型的匹配、转换、标识等。
  • 解释执行:解释型语言一般都有虚拟机来执行特定格式的字节码,

编译执行

编译阶段

编程语言可以分为编译性语言以及解释性语言,解释性语言例如PHP,Python等,解释性语言通过语言的解释器逐行解释执行。

编译语言的运行首先通过编译生成可执行文件,编译是由编译器执行的。

编译的过程可以分为以下阶段:

  • 预处理,预处理主要处理各种指令,例如C/C++语言在预处理阶段主要处理包含指令,宏指令等信息。
  • 编译,编译过程比较复杂,分为以下过程
    • 词法分析:扫描器(Scanner)将源代码分割成一系列的记号(Token),词法分析的工具有lex。
    • 语法分析:语法分析器将记号(Token)生成语法树(Syntax Tree),yacc是常用的语法分析工具。
    • 语义分析:分析语法树的语义,进行类型的匹配、转换、标识等。
    • 源代码优化:源代码优化器将整个语法树转化为中间代码(Intermediate Code),中间代码是与目标机器和运行环境无关的。中间代码使得编译器被分为前端和后端。编译器前端负责产生机器无关的中间代码;编译器后端将中间代码转化为目标机器代码。
    • 目标代码生成:代码生成。
    • 目标代码优化:代码优化。
  • 汇编,汇编器将编译好的程序翻译成机器语言指令,把这些指令打包成一种叫做可重定位目标程序的二进制文件
  • 链接,链接分为静态链接,动态链接等
    • 链接器将各个已经编译成机器指令的目标文件链接起来,经过重定位过后输出一个可执行文件。
    • 装载可执行文件以及依赖的共享对象。
    • 动态链接器将可执行文件和共享对象中需要重定位的位置进行修正
运行阶段

程序通过编译过程构建的软件除了单片机程序等一般不直接运行在硬件上,大型复杂的硬件例如计算机都会有操作系统,操作系统是可以直接操作CPU、内存、磁盘扇区等硬件。

操作系统一般会定义可执行程序的格式,例如windows下面的PE和linux的ELF。可以执行的目标文件主要分为两类,可重定位文件包含适合于与其他目标文件链接来创建可执行文件或者共享目标文件的代码和数据。 (Linux的*.o 文件 Windows的 *.obj文件)可执行文件(Executable File) 包含适合于执行的一个程序,此文件规定了 exec() 如何创建一个程序的进程映像。(Windows的*.exe)。

硬件如何执行这些程序呢,我们目前所使用的硬件是基于图灵机的。图灵机分为计算器,存储器等几个模块。

执行程序的过程可以分为加载程序,分配内存,创建进程等过程。