计算机中的符号是什么意思?


author: hjjdebug
date: 2026年 01月 08日 星期四 12:45:41 CST
descrip: 计算机中的符号是什么意思?


文章目录

  • 甲. 什么叫符号?
    • 0 下面是测试代码
    • 1 用 $ nm test 可列出其所有符号,非常简明
    • 2. 用 $ readelf -s test 有对符号更细致的描述.
    • 3. 用 $ readelf --dyn-syms test 会只列出动态符号
    • 4 符号的构成要素
    • 5 符号在计算机中是如下定义的.
    • 6 补充1: type 的 定义
    • 7 补充2: bind 的 定义
    • 8 补充3: visibility 的 定义, 空间留了一个byte, 256种可能,但实际只有4种
    • 9 补充4: section header index, 留了2个bytes, 默认是索引号, 但也有几个特例.
    • 10. 小结:

符号, 符号化调试, 计算机编译,连接,调试离不开符号,到底什么是符号呢?

甲. 什么叫符号?

研究符号, 也应该从hello-world 开始, 这里的符号,就是elf文件中的符号

0 下面是测试代码

$ cat test.c#include"stdio.h"intmain(){printf("hello\n");return0;}

把它编译成test 可执行文件
$ gcc -g -no-pie -o test test.c

对于名叫test 的elf 文件,

1 用 $ nm test 可列出其所有符号,非常简明

$ nm test0000000000601030B __bss_start0000000000601030b completed.76980000000000601020D __data_start0000000000601020W data_start0000000000400440t deregister_tm_clones0000000000400430T _dl_relocate_static_pie00000000004004b0 t __do_global_dtors_aux0000000000600e18t __do_global_dtors_aux_fini_array_entry0000000000601028D __dso_handle0000000000600e20d _DYNAMIC0000000000601030D _edata0000000000601038B _end0000000000400574T _fini00000000004004e0t frame_dummy0000000000600e10t __frame_dummy_init_array_entry00000000004006c4 r __FRAME_END__0000000000601000d _GLOBAL_OFFSET_TABLE_ w __gmon_start__000000000040058c r __GNU_EH_FRAME_HDR00000000004003c8 T _init0000000000600e18t __init_array_end0000000000600e10t __init_array_start0000000000400580R _IO_stdin_used0000000000400570T __libc_csu_fini0000000000400500T __libc_csu_init U __libc_start_main@@GLIBC_2.2.500000000004004e7T main U puts@@GLIBC_2.2.50000000000400470t register_tm_clones0000000000400400T _start0000000000601030D __TMC_END__

一下子多出来这么多符号, 其实从源代码中,我们只知道main 符号 和 printf 符号,
printf 在这里被puts@@GLIBC_2.2.5 替代了.
其它的先不管了.
由此看出符号的几个特点:

  1. 符号首先要有名字,用以区别是这个符号还是哪个符号
    计算机中用一个4字节数表示.
    为什么是4字节?
    因为所有的名字字符串构成一个字符串节,排列在一起,这个4字节32位数,
    表示这个名字的首个字符在字符串节中的偏移位置, 4字节足够使用了

  2. 符号要有值. 这是符号存在的意义.
    例如:
    00000000004004e7 T main
    其值,在64bits 机器上占用8bytes 地址值,也足够大了

  3. 符号有类型. 例如这里的T,t,D,d,w,B,R 等等

2. 用 $ readelf -s test 有对符号更细致的描述.

它会列出动态符号与静态符号集合.

3. 用 $ readelf --dyn-syms test 会只列出动态符号

$ readelf--dyn-syms test Symbol table'.dynsym'contains4entries:Num:Value Size Type Bind Vis Ndx Name0:00000000000000000NOTYPE LOCAL DEFAULT UND1:00000000000000000FUNC GLOBAL DEFAULT UND puts@GLIBC_2.2.5(2)2:00000000000000000FUNC GLOBAL DEFAULT UND __libc_start_main@GLIBC_2.2.5(2)3:00000000000000000NOTYPE WEAK DEFAULT UND __gmon_start__

关注 puts(即转义的printf), 及__libc_start_main
动态符号, 其值暂时为0, 将来由loader 去确定符号具体的数值即内存偏移地址.
静态符号太长 66项,

Symbol table'.symtab'contains66entries:Num:Value Size Type Bind Vis Ndx Name0:00000000000000000NOTYPE LOCAL DEFAULT UND1:00000000004002380SECTION LOCAL DEFAULT12:00000000004002540SECTION LOCAL DEFAULT23:00000000004002740SECTION LOCAL DEFAULT34:00000000004002980SECTION LOCAL DEFAULT45:00000000004002b80SECTION LOCAL DEFAULT56:00000000004003180SECTION LOCAL DEFAULT67:00000000004003560SECTION LOCAL DEFAULT78:00000000004003600SECTION LOCAL DEFAULT89:00000000004003800SECTION LOCAL DEFAULT910:00000000004003b00SECTION LOCAL DEFAULT1011:00000000004003c80SECTION LOCAL DEFAULT1112:00000000004003e00SECTION LOCAL DEFAULT1213:00000000004004000SECTION LOCAL DEFAULT1314:00000000004005740SECTION LOCAL DEFAULT1415:00000000004005800SECTION LOCAL DEFAULT1516:000000000040058c0SECTION LOCAL DEFAULT1617:00000000004005c80SECTION LOCAL DEFAULT1718:0000000000600e100SECTION LOCAL DEFAULT1819:0000000000600e180SECTION LOCAL DEFAULT1920:0000000000600e200SECTION LOCAL DEFAULT2021:0000000000600ff00SECTION LOCAL DEFAULT2122:00000000006010000SECTION LOCAL DEFAULT2223:00000000006010200SECTION LOCAL DEFAULT2324:00000000006010300SECTION LOCAL DEFAULT2425:00000000000000000SECTION LOCAL DEFAULT2526:00000000000000000SECTION LOCAL DEFAULT2627:00000000000000000SECTION LOCAL DEFAULT2728:00000000000000000SECTION LOCAL DEFAULT2829:00000000000000000SECTION LOCAL DEFAULT2930:00000000000000000SECTION LOCAL DEFAULT3031:00000000000000000FILE LOCAL DEFAULT ABS crtstuff.c32:00000000004004400FUNC LOCAL DEFAULT13deregister_tm_clones33:00000000004004700FUNC LOCAL DEFAULT13register_tm_clones34:00000000004004b00FUNC LOCAL DEFAULT13__do_global_dtors_aux35:00000000006010301OBJECT LOCAL DEFAULT24completed.769836:0000000000600e180OBJECT LOCAL DEFAULT19__do_global_dtors_aux_fin37:00000000004004e00FUNC LOCAL DEFAULT13frame_dummy38:0000000000600e100OBJECT LOCAL DEFAULT18__frame_dummy_init_array_39:00000000000000000FILE LOCAL DEFAULT ABS test.c40:00000000000000000FILE LOCAL DEFAULT ABS crtstuff.c41:00000000004006c40OBJECT LOCAL DEFAULT17__FRAME_END__42:00000000000000000FILE LOCAL DEFAULT ABS43:0000000000600e180NOTYPE LOCAL DEFAULT18__init_array_end44:0000000000600e200OBJECT LOCAL DEFAULT20_DYNAMIC45:0000000000600e100NOTYPE LOCAL DEFAULT18__init_array_start46:000000000040058c0NOTYPE LOCAL DEFAULT16__GNU_EH_FRAME_HDR47:00000000006010000OBJECT LOCAL DEFAULT22_GLOBAL_OFFSET_TABLE_48:00000000004005702FUNC GLOBAL DEFAULT13__libc_csu_fini49:00000000006010200NOTYPE WEAK DEFAULT23data_start50:00000000000000000FUNC GLOBAL DEFAULT UND puts@@GLIBC_2.2.551:00000000006010300NOTYPE GLOBAL DEFAULT23_edata52:00000000004005740FUNC GLOBAL DEFAULT14_fini53:00000000000000000FUNC GLOBAL DEFAULT UND __libc_start_main@@GLIBC_54:00000000006010200NOTYPE GLOBAL DEFAULT23__data_start55:00000000000000000NOTYPE WEAK DEFAULT UND __gmon_start__56:00000000006010280OBJECT GLOBAL HIDDEN23__dso_handle57:00000000004005804OBJECT GLOBAL DEFAULT15_IO_stdin_used58:0000000000400500101FUNC GLOBAL DEFAULT13__libc_csu_init59:00000000006010380NOTYPE GLOBAL DEFAULT24_end60:00000000004004302FUNC GLOBAL HIDDEN13_dl_relocate_static_pie61:000000000040040043FUNC GLOBAL DEFAULT13_start62:00000000006010300NOTYPE GLOBAL DEFAULT24__bss_start63:00000000004004e723FUNC GLOBAL DEFAULT13main64:00000000006010300OBJECT GLOBAL HIDDEN23__TMC_END__65:00000000004003c80FUNC GLOBAL DEFAULT11_init

拣我们已知的. main, puts
能看懂名字的. _start, _init, __bss_start, _end, _edata, test.c, crtstuff.c,
其它就先不管了.

4 符号的构成要素

用readelf, 我们看到符号不仅有value, 而且还有size,
不仅有type, 而且还有Bind, Visibility, 还有index.
名称呢? 有的符号没有名称.
下面就要从计算机的角度来解释一下什么叫符号了.
不是含糊的概念, 而是准确的概念.
以64位cpu 为例.

  1. 前面说了, name 占4个bytes
  2. value 是一个8bytes 地址值
  3. size 是一个8bytes, 的大小值, 例如 main 函数,占用23bytes 大小
  4. index 是什么意思? 是说该符号属于哪个section, index 是section的index,用word表示,2bytes
  5. 把type 和 binding 合成一个byte, type 占低4bits, bind 占高4bits

5 符号在计算机中是如下定义的.

typedefstruct{Elf64_Word st_name;/* Symbol name (string tbl index) */4字节unsignedcharst_info;/* Symbol type and binding */1字节unsignedcharst_other;/* Symbol visibility */1字节 Elf64_Section st_shndx;/* Section index */2字节 Elf64_Addr st_value;/* Symbol value */8字节 Elf64_Xword st_size;/* Symbol size */8字节}Elf64_Sym;对大小还不敢确认,看看其elf64.h 中的定义typedefuint32_tElf64_Word;typedefuint16_tElf64_Section;typedefuint64_tElf64_Addr;typedefuint64_tElf64_Xword;

6 补充1: type 的 定义

switch(sym_type) { case 0: return "NOTYPE"; case 1: return "OBJECT"; case 2: return "FUNC"; case 3: return "SECTION"; case 4: return "FILE"; case 6: return "TLS"; case 7: return "NUM"; case 10: return "LOOS"; case 12: return "HIOS"; default: return "UNKNOWN"; }

7 补充2: bind 的 定义

switch(sym_bind) { case 0: return "LOCAL"; case 1: return "GLOBAL"; case 2: return "WEAK"; case 3: return "NUM"; case 10: return "UNIQUE"; case 12: return "HIOS"; case 13: return "LOPROC"; default: return "UNKNOWN";

8 补充3: visibility 的 定义, 空间留了一个byte, 256种可能,但实际只有4种

switch(sym_vis) { case 0: return "DEFAULT"; //可见 case 1: return "INTERNAL"; case 2: return "HIDDEN"; case 3: return "PROTECTED"; default: return "UNKNOWN"; }

9 补充4: section header index, 留了2个bytes, 默认是索引号, 但也有几个特例.

switch(shdr_idx) { case SHN_ABS: return "ABS"; case SHN_COMMON: return "COM"; case SHN_UNDEF: return "UND"; case SHN_XINDEX: return "COM"; default: return std::to_string(shdr_idx); }

#define SHN_UNDEF 0 /* Undefined section/
#define SHN_ABS 0xfff1 /
Associated symbol is absolute/
#define SHN_COMMON 0xfff2 /
Associated symbol is common/
#define SHN_XINDEX 0xffff /
Index is in extra table. */

10. 小结:

我们从形态,构造,功能方面用白话介绍了符号的概念, 希望对想了解编译,连接,调试的朋友有所帮助.
想了解重定位的概念, 请参考链接:
elf 格式 relocation 概念

参考代码: https://gitee.com/hejinjing/elf-parser.git

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

深度学习毕设选题推荐:基于python-CNN卷积神经网络对盆栽识别

博主介绍:✌️码农一枚 ,专注于大学生项目实战开发、讲解和毕业🚢文撰写修改等。全栈领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围:&am…

导师严选8个AI论文写作软件,专科生搞定毕业论文+格式规范!

导师严选8个AI论文写作软件,专科生搞定毕业论文格式规范! AI 工具助力论文写作,专科生也能轻松应对 在当今学术写作领域,AI 工具正逐步成为学生和科研工作者的得力助手。尤其是对于专科生而言,面对毕业论文的撰写压力&…

导师推荐9个一键生成论文工具,自考本科生轻松搞定毕业论文!

导师推荐9个一键生成论文工具,自考本科生轻松搞定毕业论文! AI 工具助力论文写作,自考学生不再焦虑 在当前的学术环境中,越来越多的自考本科生开始借助 AI 工具来辅助完成毕业论文。这些工具不仅能够有效降低 AIGC 率,…

两句话理解 ElasticSearch 搜索引擎数据库的作用

一个有两千万商品的商品表,如何提高根据商品名关键字检索商品的效率,搜索引擎数据库 ElasticSearch 一、个人理解 在 MySQL 数据库中有一个商品表,表中有 2 千万个商品数据,现在要根据商品名称关键字,去查找相关的商品…

程序员必看:Docker+Dify+DeepSeek本地部署大模型+知识库完整教程(含实操,建议收藏)

本文详细介绍了如何使用Docker、Dify和DeepSeek搭建本地大模型系统。通过安装Docker环境,部署Dify平台,配置DeepSeek和bge-large模型,上传私有知识库,最终创建个性化AI助手。这种本地部署方式能让大模型学习个人专业知识&#xff…

SnapShot硬盘备份软件:一款小巧强大的德国军工级数据备份方案

在系统维护、数据迁移和灾难恢复场景中,一款可靠、快速的备份工具至关重要。与Acronis True Image、Ghost等大型商业软件不同,Drive SnapShot​ 以其“小而美”的设计哲学脱颖而出。它用极小的体积实现了专业级备份软件的核心功能,尤其适合技…

【干货收藏】RAG调优完整指南:从基础到GraphRAG,提升大模型回答准确率

文章详解RAG系统调优方法,包括知识库优化(检索优化、知识沉淀、健康度检查)、高级召回排序技术(混合检索、重排序、查询扩展)及GraphRAG解决复杂查询。提出三阶段进阶路径:起步期优化分词和混合检索&#x…

mysql的分区表

1.SQL表创建 下面以时间范围进行创建(每月一个分区,表中创建了四个月的分区) 创建:CREATE TABLE test_table ( id INT NOT NULL AUTO_INCREMENT, content VARCHAR(255), create_time DATETIME NOT NULL,PRIMARY KEY (id, creat…

保姆级教程:使用Dify搭建知识库+Ollama部署本地模型,零基础也能轻松上手!

本文详细介绍了两大步骤:首先讲解如何安装配置Dify并调整文件上传限制;其次指导使用Ollama部署本地模型,包括安装配置、监听设置及模型名称获取。通过本教程,读者可掌握搭建个人知识库和本地AI服务的完整流程,适合想要…

最新APP导航下载页系统源码 带后台

非常好看的一款App导航推荐页源码,带后台,这是一款PHP源码,Thinkphp框架,这款源码安装非常便捷干净,后台添加应用及轮播广告也非常方便,网站自适应PC手机自适应,喜欢的自行部署吧!安…

AI产品经理进阶指南+大模型全栈学习路线:104G资源包助你从零到实战

文章详解AI产品经理与通用产品经理的区别、必备技能及转型路径,并系统介绍大模型七大学习阶段,从系统设计到行业应用实战。同时提供100套AI商业化方案、全套视频教程和200本PDF书籍等资源,帮助程序员和小白系统掌握大模型技术,实现…

深度学习毕设选题推荐:基于python_CNN卷积神经网络对甜点识别

博主介绍:✌️码农一枚 ,专注于大学生项目实战开发、讲解和毕业🚢文撰写修改等。全栈领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围:&am…

公众号图片圆角与阴影样式配置实战(以135编辑器为例)

摘要:本文聚焦公众号图片圆角(border-radius)与阴影(box-shadow)样式配置的核心需求,以135编辑器为实操案例,从操作步骤、参数解析到避坑指南,全流程拆解可视化样式配置的实现逻辑。…

千寻运动助手V3.1小程序源码 全开源版

会员积分流量主自动化任务全功能上线基于PHPMySQL的运动步数管理助手,支持VIP自动任务、积分体系、流量主变现,打造专属健康运动小程序项目简介:运动健康领域的全能助手在全民健身和数字化健康管理的时代背景下,一款能够激励用户运…

基于C++Qt实现邮政客户投诉工单处理系统[2026-01-07]

基于CQt实现邮政客户投诉工单处理系统[2026-01-07] 项目介绍 邮政客户投诉工单处理系统是一个基于Qt框架开发的信息管理系统,主要用于处理邮政客户的投诉工单,实现了投诉工单的创建、处理、审核、统计等全流程管理。系统支持多角色权限管理&#xff0c…

《计算机网络》深入学:组帧

在计算机网络的世界里,物理层像是一个不知疲倦的搬运工,它只负责传输比特流(0 和 1),却并不关心这些比特代表什么意义。 而数据链路层(Data Link Layer) 的核心任务之一,就是把这些…

MySQL数据误删或者误更新如何恢复(详细步骤,一看就会)

目录 本篇文章适用场景 一、下载MyFlash工具二、误删数据恢复 先检查MySQL有没有开启binlog日志演示误删除数据利用MyFlash工具 反写SQL利用mysqlbinlog 执行反写的sql二进制文件恢复完成 三、误更新数据恢复 演示误更新数据查看binlog最近的更新记录 ,确定起始、结…

空间计算开发者技能指南 2026

空间计算时代的来临:定义、生态与技术共振 “空间计算”(Spatial Computing)不仅仅是营销术语,它标志着计算平台从二维屏幕向三维物理空间的范式转移。虽然 Apple 将 visionOS 定义为空间计算操作系统,但在更广泛的开…

通信协议仿真:通信协议基础_(7).协议仿真的工具与软件

协议仿真的工具与软件 在通信协议仿真领域,选择合适的工具和软件是至关重要的。这些工具和软件可以帮助我们更高效地设计、实现和测试通信协议。本节将详细介绍一些常用的协议仿真工具及其使用方法,包括NS-3、OMNeT++、MATLAB等。 1. NS-3 NS-3(Network Simulator 3)是一…

你画我猜计时答题对战房间酒馆互动神器H5开源

让我为您介绍这个"云起SAAS小酒馆互动H5"系统。 系统介绍 这是一个云起SAAS小酒馆互动H5系统,一个完整的双人对战游戏平台。 核心功能 1. 双人游戏模式计时答题对战: 双方同步答题,统计得分和用时,得分高且用时短者胜,输方接受惩罚你画我猜对战: 一人画一人猜,画手完…