nm命令的学习以及可执行文件中的段

今天学习专家c的运行时数据结构,顺便简单地学习了一下nm命令

就目标文件而言,段是二进制文件中的简单区域里面保存了一定信息,section是ELF文件中最小组织单元,一个段包含几个section.

nm命令的作用是显示对象文件,可执行文件以及对象文件库的符号信息.这里只对可执行文件的符号信息进行研究.

以hello world 程序为例

#include <stdio.h>

int lemon[1000];
int main(){
  printf("Hello World!\n");
  return 0;
}
/*test.c*/

用gcc test.c 命令编译后默认生成 a.out 这个默认名字的文件是由链接器产生的,之所以叫a.out是因为在遥远的过去,也就是链接器还没有被发明时,汇编产生的程序

就保存在这个a.out文件中(assembler output的缩写),发明链接器后由链接器产生的文件仍然保留了这个称呼.

生成的a.out文件我们先来看看它的大小 即 ls -l a.out 以及它的各个端的大小即 size a.out

再来用nm 命令来看看符号信息 这里用了 -S 选项和 -t FORMAT 选项来方便显示.  -S选项是打印定义了的符号的大小的开关. -t FORMAT 是以十进制,十六进制

八进制来打印数字的开关.

观察一下得到的结果第一列为该符号的地址,第三列可能为该符号的大小,可以看到lemon的大小就是4000字节,最后一列为符号的名字

我们来看看第二列有大小的T,t,大小写的B,b等等

这里的大写为GLOBAL小写为LOCAL

b(B)为BSS

d(D)为DATA

t(T)为TEXT

U表示该符号在该文件中是未定义的,即在其他的文件中定义

再来看看当该数组赋值时的情况

文件的大小增加了大约4000字节

而看看可执行的文件中的段,data段大概增加了4000字节,bss段减少了大约4000字节,段总大小几乎不变

所以可以得出结论bss段并不占用可执行文件的任何空间,只是记录其大小.

再来看看把数组声明在函数中会怎样

文件的size比以前少了大约4000字节,段的总的大小也少了4000字节左右

利用nm命令看看

可以发现可执行文件已经没有lemon这个符号了,当对数组进行初始化后也一样.可见在函数中声明的数组并没有存在段中.

最后看看调试选项对可执行文件的影响

可见调试编译对可执行文件大小有影响,但对段的大小并没有影响

总结:

数据段保存在可执行文件中

bss段不保存在可执行文件中

a.out文件大小受调试状态编译的影响,而段不受影响

疑惑:

为什么说文本段是最易受优化措施影响的段.

(看完这章后来试试解决这个疑问)

原文地址:https://www.cnblogs.com/tclan126/p/8306422.html

时间: 2024-08-07 04:14:11

nm命令的学习以及可执行文件中的段的相关文章

linux中的nm命令简介

转:http://blog.csdn.net/stpeace/article/details/47089585 一般来说, 搞linux开发的人, 才会用到nm命令, 非开发的人, 应该用不到. 虽然nm很简单, 但是还是有必要写几句, 聊表心意. nm不是ni ma的缩写, 当然, 也不是ni mei的缩写, 而是names的缩写, nm命令主要是用来列出某些文件中的符号(说白了就是一些函数和全局变量等).  下面, 我们一起来看看. test.h为: [cpp] view plain cop

学习Linux系统中命令的简单方法

如果说如何快速学习.了解Linux的话,我的答案是学命令.背命令!为何呢?对于一名新手来说,去学习Linux的思想.了解Linux的架构.明白Linux中"一切皆文件"概念虽然说是没有错,是对的.但是个人认为去学习这些"高大上"的东西不是一时半会的事儿,它需要一定的时间和经验去沉淀才能掌握.那么如何最快速了解Linux并使用呢?我依然觉得学命令.背命令,掌握命令是比较笨但却是比较快的方式. 我开始学习Linux的时候,问了前辈:我入门Linux需要掌握哪些命令呢?前

nm命令中符号类型详解

摘自http://blog.csdn.net/solmyr_biti/article/details/6565479 nm命令介绍的很多,但大多不介绍其函数符号标志的含义.最近在调试动态库时常用到,其中用的最多的用法:nm -A * |grep “aaa” | c++filt  // -A 为了显示文件, c++filt转换为可读风格,好像有个参数也能实现类似功能 其他内容整理如下(原作者未知): nm用于列出目标文件的符号清单,如果没有指定目标文件,则默认为“a.out”.nm的格式如下: n

Linux中rename命令用法学习 修改文件名

如何用命令修改文件名呢?在linux下可以用rename命令,当然还可以使用mv命令,这里分享下linux rename命令的用法. 有一部分人说linux下没有rename命令,建议大家用mv命令.对rename命令和mv命令在重命名文件方面做一个比较,大家根据个人喜欢选择使用吧. mv命令,在man mv中对于mv命令的介绍:mv -move(rename) files 可以看到mv命令确实有重命名的功能,但是实际应用中,它只能对单个文件重命名,命令如下:mv [path/]oldfilen

strings和nm命令

strings和nm命令 strings 一.简介: 显示文件中的可打印字符 二.用法 strings [option(s)] [file(s)] 选项说明: -a – –all 扫描整个文件而不是只扫描目标文件初始化和装载段(缺省时,是只扫描初始化和装载段) -f –print-file-name 在显示字符串前先显示文件名 -n –bytes=[number] 找到并且输出所有NUL终止符序列 - 设置显示的最少的字符数,默认是4个字符 -t –radix={o,d,x} 输出字符的位置,基

linux下nm命令的使用

linux下强大的文件分析工具 -- nm 什么是nm nm命令是linux下自带的特定文件分析工具,一般用来检查分析二进制文件.库文件.可执行文件中的符号表,返回二进制文件中各段的信息. 目标文件.库文件.可执行文件 首先,提到这三种文件,我们不得不提的就是gcc的编译流程:预编译,编译,汇编,链接. 目标文件 :常说的目标文件是我们的程序文件(.c/.cpp,.h)经过预编译,编译,汇编过程生成的二进制文件,不经过链接过程,编译生成指令为: gcc(g++) -c file.c(file.c

android SDK adb命令入门学习

[基本介绍] 在学习android过程中,经常需要用到adb命令.ADB全称Android Debug Bridge,是android sdk里的一个工具, ADB是一个"客户端-服务器端"程序,其中客户端就是操作的的电脑,服务器端是android设备,包括实体机器戒者虚拟机.用这个命令可以直接操作管理android模拟器或者真实的andriod设备 它的主要功能有: *运行设备的shell(命令行) * 管理模拟器戒设备的端口映射 * 计算机和设备之间上传/下载文件 * 将本地apk

Raid及Mdadm命令_学习笔记

关于Raid及Mdadm命令的学习笔记: 课前小知识: 关于case的小脚本笔记: cat  << EOF d|D) show disk Information m|M) show Mem Information s|S) show swap Information EOF read -p "Please input Your Choice: " Choice while [ $Choice != "quit" ] do case $Choice in

linux命令行学习-dig(DNS查询器)

在web开发中,总要熟悉的就是http协议,而发起一个http开始前最先要经历的一个过程就是DNS解析.简单说就是域名如何最终解析到实际服务器ip的过程. 而在研究DNS解析和排除DNS解析类故障问题的时候一个强大的工具就是dig.和他对应的有个比较传统的命令nslookup,不过dig作为更新的命令,其强大而简洁可定制的输出也使得运维其开发人员使用. 实例1(访问服务器本地DNSserver查询根域名服务器):  ~#: dig ; <<>> DiG 9.3.6-P1-RedHa