inc si指令的作用_到底什么是链接,它起到了什么作用?

2023-11-14

几十年以前,计算机刚刚诞生,人们编写程序时,将所有的代码都写在同一个源文件中,经过长期的积累,程序包含了数百万行的代码,以至于人们无法维护这个程序了。于是人们开始寻找新的方法,迫切地希望将程序源代码分散到多个文件中,一个文件一个模块,以便更好地阅读和维护,这个时候,链接器就粉墨登场了。

一切都是地址

我们知道,数据是保存在内存中的,对于计算机硬件来说,必须知道它的地址才能使用。变量名、函数名等仅仅是地址的一种助记符,目的是在编程时更加方便地使用数据,当源文件被编译成可执行文件后,这些标识符都不存在了,它们被替换成了数据的地址。假设变量 a、b、c 的地址分别为 0X1000、0X1004、0X1008,加法运算的机器指令为 1010,赋值运算的机器指令为 1110,那么在C语言中实现加法运算的代码为:

c = a + b;

生成可执行文件后的机器码为:

1010  0X1000  0X1004  //将两个数据相加的值保存在一个临时区域
1110  0X1008  //将临时区域中的数据复制到地址为0X1008的内存中

编译器和链接器的一项重要任务就是将助记符替换成地址。

汇编语言的诞生

任何程序的执行,最终都要依靠计算机硬件来完成。现代计算机硬件都是大规模集成电路,它只认识高低两个电平(电压),高电平一般为 5V,用1表示,低电平一般为 0V,用0表示。也就是说,在计算机底层,没有文字、数字、图像、视频等丰富多彩的可视化元素,只有 0 和 1 两个二进制数字,这就是机器语言。计算机刚刚诞生的时候没有编程语言,人们直接使用机器语言(二进制)编程。现在假设有一种跳转指令,它的二进制形式为 0001,如果需要执行地址为 1010 的代码,那么可以这样写:

0001  1010

所谓跳转,就是在执行当前代码块时转而执行其他的代码块。从本质上讲,C语言中的函数就是一个代码块,当发生函数调用时,就会执行其他的代码块,这个过程就是通过跳转指令来完成的。

那么现在问题来了,程序并不是一写好就永远不变化的,它可能会经常被修改。比如我们在地址 1010 之前插入了其他指令,那么原来的代码就得往后移动,上面的跳转指令的跳转地址也得相应地调整。在这个过程中,程序员需要人工重新计算每个子程序或者跳转的目标地址,这种重新计算各个目标地址的过程叫做重定位(Relocation)。每次程序修改时,这些位置都要重新计算,十分繁琐又耗时,并且很容易出错。如果程序包含了多个源文件,就很可能会有跨文件的跳转,这种人工重定位的方式在程序拥有多个模块时会导致更加严重的问题。没办法,这种黑暗的程序员生活是没办法容忍的,于是先驱们发明了汇编语言(Assembly),这相比机器语言来说是个很大的进步。汇编语言使用接近人类的各种符号和标记来帮助记忆,比如用jmp表示跳转指令,用func表示一个子程序(C语言中的函数就是一个子程序)的起始地址,这种符号的方法使得人们从具体的机器指令和二进制地址中解放出来。将上面的机器指令使用汇编代码来书写:

jmp func

这样,不管在 func 之前增加或者减少了多少条指令导致 func 的地址发生了变化,汇编器在每次汇编程序的时候会重新计算 func 这个符号的地址,然后把所有使用到 func 的地方修正为新的地址,整个过程不需要人工参与。对于一个有成千上百个类似的符号的程序,人们终于摆脱了这种低级的繁琐的计算地址的工作,用一句政治口号来说就是“极大地解放了生产力”。符号(Symbol)这个概念随着汇编语言的普及被广泛接受,它用来表示一个地址,这个地址可能是一段子程序(后来发展为函数)的起始地址,也可以是一个变量的地址。

C语言的诞生

汇编语言的主要作用是为机器指令提供了助记符,大部分汇编代码和机器指令是一一对应的,这在汇编被发明的初期确实令程序员非常欣喜。后来随着软件规模的日渐庞大,代码量开始疯长,汇编语言的缺点逐渐暴露出来。汇编虽然提供了多种符号,但它依然非常接近计算机硬件,程序员要考虑很多细节问题和边界问题,并且不利于模块化开发,所以后来人们发明了C语言。C语言是比汇编更加高级的编程语言,极大地提高了开发效率,以加法为例,C语言只需要一条语句,汇编却需要四五条。

模块化开发

现代软件的规模往往都很大,动辄数百万行代码,程序员需要把它们分散到成百上千个模块中。这些模块之间相互依赖又相互独立,原则上每个模块都可以单独开发、编译、测试,改变一个模块中的代码不需要编译整个程序。

在C语言中,一个模块可以认为是一个源文件(.c 文件)。

在程序被分隔成多个模块后,需要解决的一个重要问题是如何将这些模块组合成一个单一的可执行程序。在C语言中,模块之间的依赖关系主要有两种:一种是模块间的函数调用,另外一种是模块间的变量访问。函数调用需要知道函数的首地址,变量访问需要知道变量的地址,所以这两种方式可以归结为一种,那就是模块间的符号引用。模块间依靠符号来“通信”类似于拼图版,定义符号的模块多出一个区域,引用符号的模块刚好少了那一块区域,两者刚好完美组合。如下图所示:

039fc6c9d1afc6a58e9c507ddafb0efe.png

这种通过符号将多个模块拼接为一个独立的程序的过程就叫做链接(Linking)。

1f9d113190f68ddf1dcd821eadfba490.png

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

inc si指令的作用_到底什么是链接,它起到了什么作用? 的相关文章

  • 管理node的版本

    使用 nvm 管理node版本 nvm类似 python virtualenv 使用起来更加方便 安装nvm 参见 https www jianshu com p 622ad36ee020 使用cnpm 代替 npm 安装cnpm sudo
  • mysql数据库

    mysql数据库 添加 更新 删除表 删除单条 去重查询 运算符 模糊查询 集合 逻辑 sql gt between 值1 and 值2 is NUll 排序查询 聚合函数 ifNull 列名 默认值 如果列名为空 返回默认值 分组grou
  • chown: /usr/local: Operation not permitted问题解决

    在MAC上安装homebrew事先博客进行安装 根据步骤进行下去 同样在brew update的时候出现报错 Error usr local must be writable 错误 在该文章中也给出解决办法 sudo chown R who
  • 查看python中模块的所有方法

    查看python中模块的所有方法 安装的python模块 现将查看方法总结如下 一 CMD命令行下使用pydoc命令 在命令行下运行 pydoc modules即可查看 二 在python交互解释器中使用help 查看 在交互式解释器中输入
  • 双向带头循环链表的实现

    1 学习第一步 当我们要学习和了解一个事物时 我们要做的第一步便是对这个事物有一个体的的了解 现在我们要学习双向带头循环链表的第一步也是这个 我们现在先来了解一下这种链表的结构 就像该图所呈现的那样 双向循环链表就是长这样 但是你可千万不要
  • c++中拷贝构造函数被调用的时机

    1 c 中拷贝构造函数被调用的时机 拷贝构造函数被调用的几种情况 1 当用类的一个对象去初始化该类的另一个对象时 系统会自动调用拷贝构造函数 2 将一个对象作为实参传递给一个非引用类型的形参 系统会自动调用拷贝构造函数 3 从一个返回类为非
  • qt linux 包含目录,qt – 找不到子目录的.pro文件 – 当subdir包含相对路径时

    我有一个带有子模板的顶级 pro文件 TEMPLATE subdirs SUBDIRS common tests common tests包含 pro文件 但是qmake找不到它 Could not find pro file for su
  • Padavan固件添加adbyby去广告功能

    2019独角兽企业重金招聘Python工程师标准 gt gt gt 在路由 自定义脚本 wan上下行启动后执行 添加下面脚本 bin sh sleep 30 Adbyby去广告脚本 Adbyby 1 0关闭 1启动 以下脚本请勿更改 if
  • python web后台框架面试题

    web后台框架 1 Django Flask Tornado的对比 答案 Django走的是大而全的方向 开发效率高 它的MTV框架 自带的ORM admin后台管理 自带的sqlite数据库和开发测试用的服务器 给开发者提高了超高的开发效
  • mybatits的一些常用问题

    1 mybatits的in字段查询的时候出现从小到大默认排序的情况 实现根据in字段里面的id进行排序
  • 用python收取邮件的一个实例

    背景 有一个工作邮箱 会接收许多人不断地投递的简历 由于邮件数量比较多 因此产生了一个需求 要求自动将邮件从邮件服务器取回到本地 并将邮件的基本信息存入本地的sqlite数据库 邮件的正文以单独文件的形式存放在文件夹下 实现 备注 在pyt
  • CICFlowMeter使用注意事项

    当我们安装好CICFlowMeter 导入pcap文件 点OK后发现什么也没办法输出 我们去从官网下载jnetpcap文件替换掉了原来文件即可 https sourceforge net projects jnetpcap files jn
  • idea如何创建XML文件

    1 找到File目录下的Settings打开 2 找到Editor并打开 3 找到Editor下的File and Code Templates并打开 4 先选中Files再点击 号 5 Name的值改为XML File Extension
  • 《Apache MINA 2.0 用户指南》第八章:字节缓存

    最近准备将Apache MINA 2 0 用户指南英文文档翻译给大家 但是我偶然一次百度 发现 Defonds 这位大牛已经翻译大部分文档 原文链接 http mina apache org mina project userguide c
  • Vue基础精讲 —— Vue的数据绑定和Vue的原生指令

    import Vue from vue new Vue el root template div div 数据绑定 div div 数据绑定 div div text div div 表达式不会被解析 div div
  • Everthing搜索神器,工作利器

    许多人的电脑都保存着大量的 照片 文档 电子书等文件 Everthing这款工具可以在闪电般的瞬间从你那不知名的硬盘中找到你需要的文件 Everything在第一次运行时 会建立索引数据库 千万不要错过 在这里插入图片描述 1 体积不到2M
  • 利用Vulnhub复现漏洞 - 心脏出血漏洞(CVE-2014-0160)

    心脏出血漏洞 CVE 2014 0160 Vulnhub官方复现教程 复现过程 启动环境 漏洞复现 ssltest py Vulnhub官方复现教程 https github com vulhub vulhub blob master op
  • mask rcnn模型踩坑指南 tusimple mx-maskrcnn

    mask rcnn模型踩坑指南 MxNet框架 1 环境 anaconda2 tensorflow gpu python2 7 14 pip freeze certifi 2017 11 5 Cython 0 27 3 easydict 1
  • MySQL按某个字段建立表分区_mysql表分区

    1 概述 通过删除仅包含该数据的分区 或多个分区 通常可以轻松地从分区表中删除失去其实用性的数据 相反 在某些情况下 通过添加一个或多个新分区来特别存储该数据 可以极大地促进添加新数据的过程 由于满足给定WHERE子句的数据只能存储在一个或

随机推荐

  • 基于STM32的FreeRTOS学习之中断测试实验(五)

    记录一下 方便以后翻阅 本章内容是接着上一章节进行的实际演练 1 实验目的 FreeRTOS可以屏蔽优先级低于configMAX SYSCALL INTERRUPT PRIORITY的中断 不会屏蔽高于其的中断 本次实验就是验证这个说法 本
  • nui-app vue.js项目实战---微信小程序

    基于uni app的小程序项目编写 什么是uni app uni app基于vue js开发的前端应用框架 同一套代码可以在ios 安卓 h5 以及各种小程序使用 开发工具 HBuilderX 下载开发版地址 主要是因为其模板丰富 操作简单
  • Cookie + Session 登入

    Cookie Session 登入 在讲Cookie Session 登入前 我们应该先来了解一下 为什么会有这两个东西 因为HTTP 是一种無狀態 stateless 的协议 所以每次请求都是獨立的 伺服器端无法判断本次请求和上一次请求是
  • java 远程shell脚本_java通过ssh连接服务器执行shell命令详解及实例

    java通过ssh连接服务器执行shell命令详解 java通过ssh连接服务器执行shell命令 JSch 是SSH2的一个纯Java实现 它允许你连接到一个sshd 服务器 使用端口转发 X11转发 文件传输等等 你可以将它的功能集成到
  • 抖音告白代码java,(新版失效)去抖音水印简单分析教程(附带java版代码)

    Python 纯文本查看 复制代码 20200908095807 https www iesdouyin com web api v2 aweme iteminfo item ids 6558232015454342407 ab type
  • 记录下今晚软件测试遇到的大题

    方法如下 测试用例设计方法之边界值分析方法 51Testing软件测试网 软件测试用例分析 习题完美整合版 搜档网 下面是选择排序的程序 其中datalist是数据表 它有两个数据成员 一是元素类型为Element的数组V 另一个是数组大小
  • 安装VS2019 提示 Visual C++ 2015-2019 x64 redistributable安装失败

    最近安装VS2019和UE4的时候总是弹出提示框 忘记截图了 找了张类似的 点击OK之后会弹出下面的对话框 度娘给出茫茫多的解决方案 大部分都是说缺少vc 2015或者vc 2017的相应库 需要先安装低版本库 试了大半天都不能解决 吐血
  • React Native-自定义组件之Slider

    一 背景 最近在进行原生模块改造RN的时候需要用到一个定制的可拖动进度条 但发现react native自带的Slider仅仅是在iOS平台上支持 所以决定自己来定制一个 二 设计思路 组合基础组件和View和Image 搭配PanResp
  • v-model数据绑定到对象的小技巧

    在前面写了v model obj a 后 下面的对象内不用写a这个属性 直接用空对象abj js这类弱语言 会自动将a这个属性set到obj的对象中去 例如 前面绑定了对象中的属性 在后面写对象的时候 可以不写对象属性 直接写一个空对象 在
  • 脑电特征中的微分熵(DE)计算

    最近参加了一个脑电相关的竞赛 其中有一个赛道是情绪识别 根据脑电数据将情绪进行4分类 查了一些文献 使用了包括时域 频域 空间域的一些特征 最后发现微分熵作为特征的分类效果最好 相关参考文献整理下载 https download csdn
  • vcruntime140.dll丢失的解决方法,vcruntime140.dll下载安装教程

    文件vcruntime140 dll需要在电脑打开一个浏览器才能下载顶部输入 dll修复程序 site 按下键盘的回车键打开 然后点击进入下载dll文件安装包 dll文件安装包下载需要点击解压 然后把解压好的文件点击打开 开始安装丢失的vc
  • android 复制文件速度,memcpy速度太慢?掌握这个技术让内存拷贝效率成倍提升

    memcpy是C C 的一个标准函数 原型void memcpy void dest const void src size t n 用于从源src所指的内存地址的起始位置开始拷贝n个字节到目标dest所指的内存地址的起始位置中 neon是
  • 华为OD机试真题B卷 Java 实现【字符串分隔】,附详细解题思路

    目录 专栏导读 一 题目描述 二 输入描述 三 输出描述 四 解题思路 五 Java算法源码 六 效果展示 华为OD机试 2023B卷题库疯狂收录中 刷题点这里 专栏导读 本专栏收录于 华为OD机试 JAVA 真题 A卷 B卷 刷的越多 抽
  • 如何使用Blender建3D汉字(保姆级别的详细)

    未来的游戏开发程序媛 现在的努力学习菜鸡 本专栏是我关于建模的学习笔记 本篇是如何使用Blender建3D汉字 这是这个专栏的第一篇 因为不知道把这篇放到哪里 就开了个新的 如何使用Blender建3D汉字 就这种的 如果是的话可以接着往下
  • 计算机科学和PYTHON编程导论_15_概率与分布

    随机程序 掷骰子 import random def rollDie 返回一个1 6的随机整数 return random choice 1 2 3 4 5 6 def rollN n result for i in range n res
  • Matlab回归分析

    线性回归 在实际中 对于情况较复杂的实际问题 因素不易化简 作用机理不详 可直接使用数据组建模 寻找简单的因果变量之间的数量关系 从而对未知的情形作预报 这样组建的模型为拟合模型 拟合模型的组建主要是处理好观测数据的误差 使用数学表达式从数
  • 用gdb.attach()在gdb下断点但没停下的情况及解决办法

    在python中 如果导入了pwntools 就可以使用里面的gdb attach io 的命令来下断点 但是这一次鼠鼠遇到了一个情况就是下了断点 但是仍然无法在断点处开始运行 奇奇怪怪 这是我的攻击脚本 我们运行一下 可以看到其实已经运行
  • Python入门--with语句

    with语句 上下文管理器 with语句可以自动管理上下文资源 不论什么原因跳出with块 都能确保文件的正确关闭 以此来达到释放资源的目的 with open 上下文管理器 with open a txt r as file as起个别名
  • Unity3d-游戏中的小地图制作

    方法一 利用NGJ MiniMap插件 1 导入该插件后 在Mesh Version gt Prefabs中 将NJG MiniMap 2D 拖入到场景中 2 在Hierarchy中点击MiniMap 位于NJG MiniMap 2D gt
  • inc si指令的作用_到底什么是链接,它起到了什么作用?

    几十年以前 计算机刚刚诞生 人们编写程序时 将所有的代码都写在同一个源文件中 经过长期的积累 程序包含了数百万行的代码 以至于人们无法维护这个程序了 于是人们开始寻找新的方法 迫切地希望将程序源代码分散到多个文件中 一个文件一个模块 以便更