当前位置: 首页 > news >正文

程序环境--翻译+执行

ANSI C标准下,有两种程序环境。

第1种是翻译环境,在这个环境中源代码被转换为可执行的机器指令。

翻译环境包括:预处理(预编译)+编译+汇编+链接。四个步骤。
第2种是执行/运行环境,它用于实际执行代码。

链接库分为动态和静态链接库,库(Library)其实是库文件,库文件中是常用的函数或者类,#include<>包含的是库函数,二者不是完全相同的。

链接库,是将开源的库文件进行编译链接后得到的二进制文件,不能独立运行,必须等到其它程序调用,才会被载入内存。这里不详细讲述库的知识。

VS中,编译器--cl.exe      链接器--link.exe

 预处理只会处理#开头的语句,编译阶段只校验语法,链接时才会去找实体。

预处理:

相当于根据预处理指令组装新的C/C++程序。经过预处理,会产生一个没有头文件(都已经被展开了)、宏定义(都已经替换了),没有条件编译指令(该屏蔽的都屏蔽掉了),没有特殊符号的输出文件,没有注释,这个文件的含义同原本的文件无异,只是内容上有所不同。(都是文本操作)

即非二进制指令。

生成.i文件。

编译:

将预处理完的文件逐一进行一系列词法分析、语法分析、语义分析及优化后,产生相应的汇编代码文件。编译是针对单个文件编译的,只校验本文件的语法是否有问题,不负责寻找实体。

符号汇总。

生成.s文件。

汇编:

把汇编指令变成二进制机器指令

形成符号表。符号+对应地址。(符号表为后续链接寻址做准备)

生成.o文件。elf格式,一个文件形成几个不同的段,使用readelf工具。   

链接:

通过链接器将一个个目标文件(或许还会有库文件)链接在一起生成一个完整的可执行程序。 链接程序的主要工作就是将有关的目标文件彼此相连接,也就是将在一个文件中引用的符号同该符号在另外一个文件中的定义连接起来,使得所有的这些目标文件成为一个能够被操作系统装入执行的统一整体。在此过程中会发现被调用的函数未被定义。需要注意的是,链接阶段只会链接调用了的函数/全局变量,如果存在一个不存在实体的声明(函数声明、全局变量的外部声明),但没有被调用,依然是可以正常编译执行的。

1、合并段表   2、符号表的合并和重定位。3、寻址(通过符号表寻址)

对调用的进行寻址,重定位,只声明的可以正常编译,执行

链接寻址时若找不到某调用的函数,则之后也找不到了,就会发生错误。

生成.exe文件。

声明外部没有的符号,可以正常执行,没有警告或报错。 

参考书籍《程序员的自我修养》

 运行/执行环境

1. 程序必须载入内存中。在有操作系统的环境中:一般这个由操作系统完成。在独立的环境中,程序
的载入必须由手工安排,也可能是通过可执行代码置入只读内存来完成。
2. 程序的执行便开始。接着便调用main函数。
3. 开始执行程序代码。这个时候程序将使用一个运行时堆栈(stack),存储函数的局部变量和返回
地址。程序同时也可以使用静态(static)内存,存储于静态内存中的变量在程序的整个执行过程
一直保留他们的值。
4. 终止程序。正常终止main函数;也有可能是意外终止

目录

预处理:

编译:

汇编:

链接:

 运行/执行环境


相关文章:

  • Node=>Express中间件 学习3
  • 软件测试】测试时间不够了,我很慌?项目马上发布了......
  • m序列发生器——Verilog设计
  • 云原生系列之使用 prometheus监控MySQL实战
  • 源码级别的讲解JAVA 中的CAS
  • 《嵌入式 – GD32开发实战指南》第22章 SPI
  • FreeModbus RTU 移植指南
  • C库函数文件操作(fopen、fread、fwrite、fclose)
  • QT之OpenGL深度测试
  • 初阶指针C
  • 【C++】CC++内存管理
  • 每日学术速递2.9
  • python selenium浏览器复用技术
  • Chapter4:机器人仿真
  • 我的网站上线了!
  • Java 实战开发之spring、logback配置及chrome开发神器(六)
  • js递归,无限分级树形折叠菜单
  • Js基础知识(四) - js运行原理与机制
  • Logstash 参考指南(目录)
  • Redis提升并发能力 | 从0开始构建SpringCloud微服务(2)
  • Sass 快速入门教程
  • Spring Security中异常上抛机制及对于转型处理的一些感悟
  • 基于组件的设计工作流与界面抽象
  • 今年的LC3大会没了?
  • 聊聊hikari连接池的leakDetectionThreshold
  • 容器服务kubernetes弹性伸缩高级用法
  • 使用Swoole加速Laravel(正式环境中)
  • 延迟脚本的方式
  • # MySQL server 层和存储引擎层是怎么交互数据的?
  • #Ubuntu(修改root信息)
  • (10)STL算法之搜索(二) 二分查找
  • (2)关于RabbitMq 的 Topic Exchange 主题交换机
  • (BFS)hdoj2377-Bus Pass
  • (day 12)JavaScript学习笔记(数组3)
  • (Redis使用系列) SpirngBoot中关于Redis的值的各种方式的存储与取出 三
  • (翻译)terry crowley: 写给程序员
  • (五)大数据实战——使用模板虚拟机实现hadoop集群虚拟机克隆及网络相关配置
  • (原創) 博客園正式支援VHDL語法著色功能 (SOC) (VHDL)
  • (转)Linq学习笔记
  • (转)使用VMware vSphere标准交换机设置网络连接
  • .net对接阿里云CSB服务
  • .Net下使用 Geb.Video.FFMPEG 操作视频文件
  • @javax.ws.rs Webservice注解
  • @取消转义
  • [ Linux 长征路第五篇 ] make/Makefile Linux项目自动化创建工具
  • [20150321]索引空块的问题.txt
  • [ACTF2020 新生赛]Include
  • [Android Pro] listView和GridView的item设置的高度和宽度不起作用
  • [C#基础]说说lock到底锁谁?
  • [CareerCup] 14.5 Object Reflection 对象反射
  • [HCTF 2018]WarmUp (代码审计)
  • [Java] 图说 注解
  • [LeeCode]-Divide Two Integers 不用乘除的除法运算
  • [linux] shell中的()和{}
  • [LOJ161] 仙人掌计数