Linux:符号和符号表

文章目录

  • 什么是符号?
  • 什么是符号表?
  • 全局符号和本地符号
    • 1. 全局符号:
      • symtab符号表
    • 2. 本地符号:
  • 符号在汇编阶段
  • 符号在链接阶段
    • 1.由模块 m 定义并能被其他模块引用的全局符号。
    • 2.由其他模块定义并被模块 m 引用的全局符号。
    • 3.只被模块 m 定义和引用的局部符号。
      • static 本地变量
  • QA:
    • 编译器和汇编器的区别?
    • 编译器包含汇编器吗?

什么是符号?

想象一下你在学校里,老师在黑板上写了一些字母和数字,比如"A"、“B”、“1”、“2”。这些字母和数字就是符号。在计算机编程或数学中,符号就是用来代表某个特定概念或值的标记。

举个例子,假设你写了一个计算机程序,里面有一个变量叫做"score",用来表示游戏中的分数。在这里,"score"就是一个符号,它代表了一个特定的值,即分数。

符号可以是字母、数字或其他字符的组合,它们被赋予特定的含义,让程序员或计算机能够理解并操作这些符号代表的信息。所以,通俗地说,符号就是一种用来代表东西的标记,让计算机或人能够更方便地理解和处理信息。

什么是符号表?

想象一下你在读一本书,遇到一个生词,你可能会查字典来找到这个词的解释和意义。符号表就有点像是一本程序的字典,但是不是用来解释生词的,而是用来解释程序中用到的各种符号、变量、函数等等。

在计算机程序中,我们使用各种符号(比如变量名、函数名)来表示不同的东西,就像字典中的单词一样。符号表就记录了这些符号对应的信息,比如变量的数据类型、函数的参数类型、以及它们在内存中的位置等等。

当计算机执行程序时,会根据符号表中的信息来理解和处理这些符号,就像你在阅读一本书时根据字典来理解生词一样。符号表有助于编程语言的解释器或编译器理解程序的结构和含义,使得计算机能够正确地执行你写的代码。

全局符号和本地符号

在编程中,有两种主要类型的符号:全局符号和本地符号。全局符号是在整个程序中都可见的,而本地符号仅在特定的作用域内可见。在链接器的上下文中,我们通常将这些符号称为外部符号和本地符号。

1. 全局符号:

  • 全局变量和函数是一种全局符号。它们可以在不同的文件中定义,并在整个程序中共享。
  • 链接器对全局符号感兴趣,因为它们需要在不同的目标文件之间解析引用关系,确保这些全局符号的定义能够正确地链接在一起。

symtab符号表

symtab 是符号表(Symbol Table)的缩写,用于存储程序中变量、函数和其他符号信息的数据结构。

关于 .symtab 中的符号表,它主要包含与全局符号相关的信息,因为链接器主要负责解决全局符号之间的引用关系。

本地符号,特别是本地非静态程序变量,通常不包含在符号表中,因为它们在运行时通过栈进行管理,链接器不需要关心这些细节。

这种分离全局和本地符号的处理方式有助于提高链接器的效率,并确保在链接阶段解决全局符号的引用关系时不会受到本地符号的干扰。

认识到本地链接器符号和本地程序变量不同是很重要的。
.symtab 中的符号表不包含对应于本地非静态程序变量的任何符号。这些符号在运行时在栈中被管理,链接器对此类符号不感兴趣。

.symtab 节中包含 ELF 符号表。这张符号表包含一个条目的数组。图 7-4 展示了每个条目的格式。
在这里插入图片描述
name是字符串表中的字节偏移,指向符号的以null结尾的字符串名字。

value 是符号的地址。对于可重定位的模块来说,value 是距定义目标的节的起始位置的偏移。对于可执行目标文件来说,该值是一个绝对运行时地址。

size 是目标的大小(以字节为单位)。

type 通常要么是数据,要么是函数。符号表还可以包含各个节的条目,以及对应原始源文件的路径名的条目。所以这些目标的类型也有所不同。

binding 字段表示符号是本地的还是全局的。

2. 本地符号:

  • 本地变量和本地函数是一种本地符号。它们通常只在定义它们的特定代码块(如函数)内部可见。
  • 链接器对本地符号不感兴趣,因为它们不需要在不同的目标文件之间解析引用关系。本地符号的生命周期通常限定在其定义的作用域内,例如在函数的栈帧中。

符号在汇编阶段

编译器在处理源代码时,会将源代码转换为汇编语言代码,然后将汇编语言代码输出到.s文件中。在输出的.s文件中,编译器还会将源代码中所有的函数、变量和常量等符号标记,并生成一个符号表,包含了这些符号的信息,如位置、大小等。

这些符号将在后续的汇编和链接过程中起到重要的作用,比如在汇编过程中,汇编器会根据符号表中所包含的信息来解析和生成目标二进制代码。

汇编器的作用主要有以下几个方面:

  1. 将汇编语言代码转换为机器语言代码:汇编器通过读取汇编代码源文件并将其转换为机器语言代码,创建目标文件,这个文件包含二进制代码和其他与代码相关的元信息。

  2. 符号解析:汇编器通过符号表解析代码中出现的符号,如函数和变量,以便能够正确地连接和重定位代码。

  3. 代码调试:汇编器生成的目标文件中包含了关于代码的调试信息,可以被调试器用来调试代码。

  4. 优化代码:汇编器可以通过优化代码来提高代码的执行效率,例如,通过使用更快的指令集或者重排指令的执行顺序。

符号在链接阶段

每个可重定位目标模块,我们姑且命名一个目标模块为m。

那么,模块m都有一个符号表,它包含模块m 定义和引用的符号的信息。

在链接器的上下文中,有三种不同的符号:

1.由模块 m 定义并能被其他模块引用的全局符号。

全局链接器符号对应于非静态的 C函数和全局变量。

2.由其他模块定义并被模块 m 引用的全局符号。

这些符号称为外部符号,对应于在其他模块中定义的非静态 C 函数和全局变量。

3.只被模块 m 定义和引用的局部符号。

它们对应于带 static 属性的 C函数和全局变量。这些符号在模块 m 中任何位置都可见,但是不能被其他模块引用。

static 本地变量

有趣的是,定义为带有 C static 属性的本地过程变量是不在栈中管理的。

相反,编译器在.data或bss 中为每个定义分配空间,并在符号表中创建一个有唯一名字的本地链接器符号。

比如,假设在同一模块中的两个函数各自定义了一个静态局部变量 x:

下面是一个示例代码,展示了在同一模块中的两个函数各自定义了一个静态局部变量 x,并且这些变量在.data或bss段中分配空间,而不是在栈中管理:

#include <stdio.h>

void function1() {
    static int x = 1;
    printf("Function 1: x = %d\n", x);
    x++;
}

void function2() {
    static int x = 10;
    printf("Function 2: x = %d\n", x);
    x--;
}

int main() {
    function1();
    function1();
    function2();
    function2();
    function1();

    return 0;
}

输出结果:

Function 1: x = 1
Function 1: x = 2
Function 2: x = 10
Function 2: x = 9
Function 1: x = 3

可以看到,每个函数的静态局部变量都保留了它们的状态,并且它们在每个函数调用之间都保留了它们的值。这是因为它们在.data或bss段中分配了空间,而不是在栈中管理。

注意:
利用 static 属性隐藏变量和函数名字: C程序员使用 static属性隐藏模块内部的变量和函数声明,就像你在Java 和C++中使用
public和 private 声明一样。

在C中,源文件扮演模块的角色。任何带有static属性声明的全局变量或者函数都是模块私有的。类似地,任何不带 static
属性声明的全局变量和函数都是公共的,可以被其他模块访问。尽可能用 static 属性来保护你的变量和函数是很好的编程习惯。

QA:

编译器和汇编器的区别?

编译器和汇编器都是程序开发中使用的工具,但它们的功能不同,具体区别如下:

  1. 编译器和汇编器的语言级别不同。编译器通常用来将高级语言(如C、C++、Java等)转换为汇编语言或者机器语言,而汇编器是把汇编语言转换为机器语言。

  2. 编译器和汇编器的输入和输出不同。编译器的输入是高级语言源代码,输出是汇编语言或者机器语言代码;而汇编器的输入是汇编语言代码,输出是机器语言代码。

  3. 编译器和汇编器的编译过程不同。编译器会对源代码进行词法分析、语法分析、优化和生成目标代码等多个阶段的处理,而汇编器只是简单地将汇编语言代码翻译成机器语言代码。

  4. 编译器和汇编器的处理粒度不同。编译器处理的粒度更大,它会对整个程序进行处理,包括程序中的所有函数、变量和常量等;而汇编器处理的粒度更小,它只是针对单个汇编模块进行处理。

编译器包含汇编器吗?

在一些编译器中,汇编器的功能是由编译器自身来实现的,这些编译器被称为“集成编译器”或“自包含编译器”(self-contained compiler)。这种编译器可以直接将高级语言源代码转化成目标机器的机器语言代码,而不需要借助其他汇编器的支持。

但也有一些编译器是不包含汇编器的。在这种情况下,编译器只负责将高级语言源代码转换成汇编语言代码,然后再使用独立的汇编器将汇编语言代码转换成机器语言代码。这种分离的方式可以让用户有更多的选择,可以灵活地选择不同的汇编器来适应不同的需求。

是否包含汇编器取决于不同的编译器实现,而不是编译器的必要组成部分。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/238378.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

电脑长截图、滚动截图软件!早用早享受!

FastStone Capture软件在屏幕捕捉、滚动截屏、屏幕录制、图片处理方面能力十分突出&#xff0c; 帮助用户以专业的方式来创建所需图片或视频。 最新版本 : FastStone Capture 10.3 软件大小 : 7.75MB 适配系统 : Windows Vista/7/8/10/11&#xff0c;WinXP 软件名称&#xff1a…

VCSA7.0加入Windows AD域失败的处理过程

一、问题现象 vcsa7.0加入AD域时提示“Idm client exception: Error trying to join AD, error code 2453” 二、处理过程 &#xff08;一&#xff09;检查是否DNS问题 查看dns是否设置正确&#xff0c;如下&#xff1a; 1. Enable SSH on VCSA. 2. Command> shell 3…

微信小程序---wxs脚本

WXS&#xff08;WeiXin Script&#xff09;是小程序的一套脚本语言&#xff0c;结合 WXML&#xff0c;可以构建出页面的结构。 WXS 与 JavaScript 是不同的语言&#xff0c;有自己的语法&#xff0c;并不和 JavaScript 一致。 1.wxs和JavaScript的区别 2.wxs脚本基础语法 &a…

短视频引流获客系统:引领未来营销的新潮流

在这个信息爆炸的时代&#xff0c;短视频已经成为了人们获取信息的主要渠道之一。而随着短视频的火爆&#xff0c;引流获客系统也逐渐成为了营销领域的新宠。本文将详细介绍短视频引流获客系统的开发流程以及涉及到的技术&#xff0c;让我们一起来看看这个引领未来营销的新潮流…

CRAMdb:动物微生物组的组成和功能综合数据库

中国中医科学院陈同、石河子大学胡圣伟、倪伟及团队在Nucleic Acids Research发表与动物相关的微生物数据CRAMdb&#xff0c;数据库中包含9430种细菌、278种古细菌、2216种真菌和458种病毒等超1.2万种微生物。与同类型其他数据库对比&#xff0c;CRAMdb囊括微生物更加广泛&…

R语言,table()函数实现统计每个元素出现的频数+并将最终统计频数结果转换成dataframe数据框形式

在 R中&#xff0c;要统计dataframe数据框中每个元素出现的频数&#xff0c;可以使用table()函数。以下是一个示例&#xff1a; 目录 一、创建数据 二、统计第一列每个元素出现的频数 三、统计第二列每个元素出现的频数 四、将频数结果转换为数据框&#xff0c;并改列名 一…

keil生成bin文件(通用型)

有些时候需要在keil里面生成bin文件&#xff0c;但找到的各种方式五花八门&#xff0c;特别是要填写文件路径等没有通用性&#xff0c;搞个不同的工程就得改下&#xff0c;找到这个跟路径无关的代码&#xff0c;进行记录下。 首先还是点开keil的设置&#xff1a; 按照上面的图…

多维时序 | MATLAB实现SAO-CNN-BiGRU-Multihead-Attention多头注意力机制多变量时间序列预测

多维时序 | MATLAB实现SAO-CNN-BiGRU-Multihead-Attention多头注意力机制多变量时间序列预测 目录 多维时序 | MATLAB实现SAO-CNN-BiGRU-Multihead-Attention多头注意力机制多变量时间序列预测预测效果基本介绍模型描述程序设计参考资料 预测效果 基本介绍 MATLAB实现SAO-CNN-B…

Flask template+Vue +项目中include引入其他模版(其他模版也会用到vue)的使用探索

项目背景是&#xff1a;团队的历史项目&#xff0c;是flask tmeplate写的前段页面。然后我在一个页面A.html中引入了vue文件&#xff0c;使用了vueelement_ui技术。现在想在此A页面中插入另外一个页面B.html的内容&#xff08;试图tab分开&#xff09;&#xff0c;因为入口只有…

Cython笔记:基本使用方法

1 Cython 介绍 Cython 是一种编程语言&#xff0c;用于编写 C 扩展的 Python 模块。它结合了 Python 的易用性和 C 的执行效率&#xff0c;旨在提高特定类型的任务的性能&#xff0c;特别是涉及大量数值计算的任务。 1.2 几个特征 1.2.1 Python 语法的基础 Cython 的大部分语…

Echarts 折线图 颜色填充 标记点 相关设置

数据 const xData [小米, 三星, 苹果] const yData [2451, 5415, 4012]配置项 {xAxis: {type: category,data: xData},yAxis: {type: value},series: [{type: line, //设置折线图data: yData,}] }曲线图&#xff08;平滑过度&#xff09; smooth: true内容填充&#xff08;…

HTML如何使用图片链接

文章目录 图片链接的使用常见图片类型PNGJPGGIFBMP 图片链接的使用 在 HTML 中&#xff0c;图像由 标签定义。 是空标签&#xff0c;意思是说&#xff0c;它只包含属性&#xff0c;并且没有闭合标签。 语法&#xff1a; <img src”图片路径" title“鼠标悬浮在图片上…

甲醛处理企业网站效果如何

甲醛往往是新装房间主所担心的问题&#xff0c;而甲醛处理公司则可以处理甲醛问题&#xff0c;市场需求也比较高&#xff0c;虽然具备同城服务属性&#xff0c;但外地或连锁经营也非常适合&#xff0c;而品牌们也遇到一些痛点&#xff1a; 1、品牌宣传拓客难 甲醛处理公司也需…

AI数字人直播能力堪比真人涌入直播大军!

近几年&#xff0c;国内外电商直播产业飞速发展。相关报告显示&#xff0c;截至2022年12月&#xff0c;电商直播用户规模为5.15亿人次&#xff0c;占网民数量的48.2%&#xff0c;总结来说&#xff0c;近一半的网民都在各类直播间购买过商品。 但是随着直播行业不断发展&#xf…

14-Kafka-Day02

第 4 章 Kafka Broker 4.1 Kafka Broker 工作流程 4.1.1 Zookeeper 存储的 Kafka 信息 &#xff08;1&#xff09;启动 Zookeeper 客户端。 bin/zkCli.sh 因为你在配置kafka的时候指定了它的名字。 &#xff08;2&#xff09;通过 ls 命令可以查看 kafka 相关信息。 [zk: …

【算法】算法题-20231211

这里写目录标题 一、387. 字符串中的第一个唯一字符二、1189. “气球” 的最大数量三、1221. 分割平衡字符串 一、387. 字符串中的第一个唯一字符 简单 给定一个字符串 s &#xff0c;找到 它的第一个不重复的字符&#xff0c;并返回它的索引 。如果不存在&#xff0c;则返回…

C++ Qt开发:LineEdit单行输入组件

Qt 是一个跨平台C图形界面开发库&#xff0c;利用Qt可以快速开发跨平台窗体应用程序&#xff0c;在Qt中我们可以通过拖拽的方式将不同组件放到指定的位置&#xff0c;实现图形化开发极大的方便了开发效率&#xff0c;本章将重点介绍LineEdit单行输入框组件的常用方法及灵活运用…

加减乘除简单吗?不,一点都不,利用位运算实现加减乘除(代码中不含+ - * /)

文章目录 &#x1f680;前言&#x1f680;异或运算以及与运算&#x1f680;加法的实现&#x1f680;减法的实现&#x1f680;乘法的实现&#x1f680;除法的实现 &#x1f680;前言 这也是阿辉开的新专栏&#xff0c;知识将会很零散不成体系&#xff0c;不过绝对干货满满&…

算法通关村——滑动窗口高频问题

滑动窗口之最长子串 无重复字符的最长子串 LeetCode3. 给定一个字符串s&#xff0c;请你找出其中不含有重复字符的最长子串的长度。 示例&#xff1a; 输入&#xff1a;s “abcabcbb” 输出&#xff1a;3 解释&#xff1a;因为无重复字符的最长子串是"abc"&#…

Socket介绍及使用Java实现socket通信前后端示例代码

本文介绍一下再Java中Socket的实现。 目录 一、需要掌握 二、程序源码 三、运行演示 一、介绍 Java Socket实现实时接收TCP消息需要客户端和服务端两个部分。 二、JavaSocket源码示例 客户端后台部分代码 public class Client {public static void main(String[] args)…