Linux size命令详解

发布于:2025-06-26 ⋅ 阅读:(12) ⋅ 点赞:(0)

size 命令在 Linux 中是用于分析二进制文件(通常是可执行文件或目标文件)各个内存段(Section/Segment)大小的一个实用工具。它从文件(通常是 ELF 格式)的头部信息中提取关键内存区域的大小信息,并以简洁的方式呈现出来。

核心功能:报告二进制文件的关键段(Section/Segment)大小

它主要报告以下三个经典段的大小:

  1. text (代码段/文本段):

    • 存放程序的实际执行代码(机器指令)。
    • 通常是只读的(Read-Only)。
    • 该段的大小在程序加载后一般固定不变。
  2. data (数据段):

    • 存放已初始化的全局变量和静态变量(包括初始化为非零值的)。
    • 该段是可读写的(Read-Write)。
    • 程序启动时,这些变量就从文件中加载了初始值。该段的大小在运行时也可能改变(如果使用动态内存分配,但初始大小是固定的)。
  3. bss (Block Started by Symbol / 未初始化数据段):

    • 存放未初始化初始化为零的全局变量和静态变量。
    • 该段也是可读写的(Read-Write)。
    • 关键点: bss 段在磁盘上的文件大小非常小(通常只记录一个长度信息)。操作系统在加载程序时,会根据这个长度信息在内存中分配相应大小的空间,并将该区域初始化为零。因此,bss 段主要影响的是程序在运行时占用的内存(RAM)大小,而不是磁盘上文件的大小

输出解读:

运行 size 命令的基本输出格式(Berkeley 格式,默认)如下:

$ size /bin/ls
   text    data     bss     dec     hex filename
 139304    4760    2760  146824   23d88 /bin/ls
  • text: 139304 字节 - 这是 ls 命令代码指令的大小。
  • data: 4760 字节 - 这是 ls 命令中已初始化的全局/静态变量的大小。
  • bss: 2760 字节 - 这是 ls 命令中未初始化或初始化为零的全局/静态变量在运行时所需要的内存大小(磁盘文件几乎不占空间)。
  • dec: 146824 字节 - 这是 text + data + bss 的总和(十进制表示)。注意:并不完全等于程序在磁盘上的文件大小(因为文件还包含其他信息如 ELF 头、节头表、符号表、调试信息等),也不完全等于程序加载到内存后的总占用(内存占用还要加上堆、栈、共享库等)。但它是一个重要的指标,尤其对于嵌入式系统等资源受限环境,关注程序本身代码和静态数据的内存占用。
  • hex: 23d88 字节 - 是 dec 总和的十六进制表示。
  • filename: 被分析的文件名。

常用选项:

  • -A / --format=sysv: 使用 System V 风格的更详细的输出格式。它会列出所有的段(Section),而不仅仅是 text/data/bss。输出通常包括:

    • section: 段的名称 (如 .text, .rodata, .data, .bss, .comment, .note.ABI-tag, .eh_frame, .got, .got.plt, .dynsym, .dynstr, .rela.dyn, .rela.plt 等)。
    • size: 该段在文件中的大小(字节)。
    • vma / lma: 虚拟内存地址/加载内存地址(通常相同)。
    • type: 段的类型(如 PROGBITS 程序数据/代码, NOBITS.bss 在文件中不占空间)。
    • attr: 段的属性标志(如 W 可写, A 可分配, X 可执行)。
    • 最后也会给出 text/data/bss 的总计。
    $ size -A /bin/ls
    /bin/ls  :
    section             size      addr
    .interp              28       792
    .note.gnu.property   32       824
    .note.gnu.build-id   36       856
    .note.ABI-tag        32       892
    .gnu.hash           228       928
    .dynsym            3096      1156
    .dynstr            1953      4252
    .gnu.version        258      6205
    .gnu.version_r       48      6464
    .rela.dyn           984      6512
    .rela.plt          1704      7496
    .init                27      9200
    .plt               1136      9232
    .text            131940     10368
    .fini                 9    142308
    .rodata           15000    142336
    .eh_frame_hdr     13924    157336
    .eh_frame         56400    171260
    .init_array          16   1367640
    .fini_array           8   1367656
    .data.rel.ro       1008   1367664
    .dynamic            560   1368672
    .got                440   1369232
    .data               400   1369680
    .bss                536   1370080
    ... (可能还有其他段) ...
    Total            246216
    
  • -B / --format=berkeley: 显式指定使用 Berkeley 格式(默认格式)。输出就是上面例子中的 text/data/bss/dec/hex/filename 行。

  • -d / -o / -x / --radix=8|10|16: 指定输出数字的进制。

    • -d / --radix=10: 十进制(默认)。
    • -o / --radix=8: 八进制。
    • -x / --radix=16: 十六进制。
    • 例如 size -x /bin/ls 会以十六进制显示 text/data/bss/dec 列。
  • -t / --totals: 当同时分析多个文件时(如 size *.o),在最后一行显示所有文件各列的总和。

    $ size -t *.o
    ... (各个.o文件的输出) ...
    text    data     bss     dec     hex filename
    ... (各个.o文件的输出) ...
     3220     104       8    3332     d04 (TOTALS)
    
  • --help: 显示帮助信息。

  • --version: 显示 size 命令的版本信息。

典型用途:

  1. 嵌入式开发/资源优化: 在内存和存储空间极其有限的嵌入式系统中,开发者需要精确了解程序代码和静态数据(text+data)的大小,以及未初始化数据(bss)将占用多少运行时内存。size 是优化程序内存占用的关键工具。
  2. 分析程序组成: 快速了解一个程序的主要组成部分大小。代码量大(text)还是全局数据多(data+bss)?使用 -A 选项可以更详细地查看具体是哪些段占用了空间(例如 .rodata 只读数据大不大?)。
  3. 比较不同版本/编译选项: 在修改代码或调整编译器优化选项(如 -Os 优化大小, -O2 优化速度)后,使用 size 比较生成的二进制文件大小变化,评估优化效果。
  4. 排查体积异常: 如果发现一个程序的文件大小或内存占用异常大,可以用 size(特别是 size -A)初步判断是代码段、数据段还是未初始化数据段过大,缩小排查范围。
  5. 理解程序加载: 帮助理解程序从磁盘加载到内存的过程(text/data 从文件加载,bss 在内存中清零分配)。

重要注意事项:

  • size 报告的是静态分配的内存区域大小(代码、全局/静态变量)。它不报告程序运行时动态分配的内存(堆 - heap)或栈内存(stack)。这些动态内存的使用情况需要用其他工具(如 top, htop, free, valgrind)来监控。
  • 输出的 dec (总十进制大小) 不等于磁盘文件大小(文件包含更多元数据)。
  • 输出的 dec (总十进制大小) 不等于程序运行时的总内存占用(还需加上堆、栈、共享库、内核数据结构等)。
  • 对于动态链接库(.so),size 主要显示库本身的代码和数据,其加载后的内存占用还会受使用它的程序影响。
  • 现代程序通常链接了动态库 (glibc 等),size 显示的大小不包括这些动态库的大小(它们在运行时才加载)。

总结:

size 命令是一个简单但强大的工具,用于剖析 Linux 二进制文件(可执行文件、目标文件、库文件)中关键内存区域(text代码段、data已初始化数据段、bss未初始化数据段)的大小。它是开发者,尤其是嵌入式系统开发者,进行程序大小分析和内存优化不可或缺的工具。通过其默认的 Berkeley 格式可以快速获取核心大小信息,而 -A 选项则提供更详细的段级别分析。理解 textdatabss 的含义及其对磁盘占用和运行时内存占用的不同影响是使用 size 的关键。


您的问题切中了关键点!我们来详细拆解每个段(Section/Segment),结合具体例子说明代码和字符串的存储位置。

核心概念:

  • 段 (Section/Segment): 是二进制文件(ELF格式)中具有相同属性(如只读、可执行、可写)的数据块。链接器会根据这些属性将不同的数据/代码归类到不同的段,操作系统加载程序时会根据段的属性设置内存页的权限。
  • 文本段/代码段 (.text): 存放可执行的机器指令。这是您编写的函数(如 main(), calculate())编译成的CPU能直接运行的二进制码。
  • 数据段不仅仅只有 .data.bss 现代编译器会生成更精细的段,比如 .rodata 来存放只读数据(如字符串常量)。

详解各段及示例:

假设我们有一个简单的C程序 simple_program.c

#include <stdio.h>

const double PI = 3.1415926535; // 全局常量,已初始化
int global_initialized = 42;     // 全局变量,已初始化(非零)
int global_uninitialized;        // 全局变量,未初始化 (或视为初始化为0)
static int static_initialized = 100; // 静态变量,已初始化

void print_message(const char* msg) {
    printf("%s\n", msg);
}

int main() {
    char local_string[] = "This is a local string"; // 局部变量(栈上,不在这些段里!)
    static int static_local_uninitialized; // 局部静态变量,未初始化 (在 .bss)

    printf("Hello, World! PI is %f\n", PI); // "Hello, World! PI is %f\n" 是字符串常量
    print_message("A function call message"); // "A function call message" 是字符串常量

    return 0;
}

编译它:gcc -o simple_program simple_program.c

1. 文本段/代码段 (.text)

  • 内容: 纯粹的可执行机器指令。 包括 main() 函数、print_message() 函数、printf 库函数内部的指令等编译后生成的CPU指令码。
  • 属性: 只读 (Read-Only)可执行 (eXecutable)。程序运行期间,这些指令不应该被修改。
  • 您的字符串在里面吗? 不在! 您代码中像 "Hello, World! PI is %f\n""A function call message" 这样的字符串常量 (String Literals) 并不直接放在 .text 段里。它们属于只读数据,会被放在另一个专门的段 .rodata (Read-Only Data) 中。.text 段只包含操作这些字符串的指令(例如,将字符串地址加载到寄存器的指令、调用 printf 的指令)。
  • size 命令中的 text 列: 主要就是这个 .text 段的大小,但也可能包含其他具有可执行权限的段(极少见)。

2. 只读数据段 (.rodata)

  • 内容: 只读的全局数据。
    • 字符串常量: 程序中所有用双引号括起来的字符串(如 "Hello, World!...", "A function call message", "%s\n", "%f\n")。
    • 全局常量:const 关键字声明的全局静态常量(且通常是基本类型或简单聚合类型)。示例中的 const double PI = 3.1415926535; 很可能会被放在这里。
    • 其他编译器生成的只读数据(如某些跳转表)。
  • 属性: 只读 (Read-Only)不可执行。程序运行期间不能修改这些数据。
  • 位置:size 的默认 (Berkeley) 输出中,.rodata 通常被包含在 text 列里一起计算大小! 这是因为它们都位于加载后只读的内存页中,且历史上 .rodata 没有严格分离。要看到 .rodata 的独立大小,必须使用 size -A (SysV格式)。
  • 示例关联: 程序里所有的硬编码字符串和 PI 都住在这里。

3. 已初始化数据段 (.data)

  • 内容: 已初始化(且初始值非零)的全局变量和静态变量。
    • 已初始化的全局变量: int global_initialized = 42;
    • 已初始化的静态变量 (全局或局部): static int static_initialized = 100; (例子中在全局,局部静态初始化也一样)
  • 属性: 可读写 (Read-Write)。程序启动时,这些变量就从磁盘上的二进制文件加载了它们的初始值(这里是42和100)。程序运行期间可以修改它们。
  • size 命令中的 data 列: 主要就是这个 .data 段的大小。

4. 未初始化数据段 (Block Started by Symbol - .bss)

  • 内容: 未初始化或显式初始化为零的全局变量和静态变量。
    • 未初始化的全局变量: int global_uninitialized;
    • 未初始化的静态变量 (全局或局部): static int static_local_uninitialized; (例子中的局部静态)
    • 初始化为零的全局/静态变量: int global_zero = 0; 也会被优化放到这里。
  • 关键特性:磁盘空间 vs 内存空间
    • 在磁盘上的文件里: .bss 段本身几乎不占用磁盘空间。它只在ELF文件中记录一个信息:“程序加载时,请给我预留 X 字节的内存,并把这块内存都清零”。
    • 在内存中: 当操作系统加载程序时,它会根据 .bss 段记录的大小 X,在进程的地址空间中分配 X 字节的可读写内存区域(通常紧跟在 .data 段之后),并将该区域全部初始化为0。这时变量 global_uninitializedstatic_local_uninitialized 的值就是0。
  • 属性: 可读写 (Read-Write)
  • size 命令中的 bss 列: 显示的就是这个在运行时需要预留并清零的内存区域的大小 X。它直接影响程序启动后的内存占用(RAM),但对磁盘上的可执行文件大小影响微乎其微。

5. 其他常见段 (通过 size -A 可见)

  • .comment: 包含编译器版本信息等注释。
  • .note.*: 包含ABI标签、构建ID等元数据。
  • .eh_frame, .eh_frame_hdr: 用于异常处理(C++异常, DWARF unwind)。
  • .init, .fini: 包含程序初始化和退出时执行的代码(由启动代码调用)。
  • .plt (Procedure Linkage Table), .got (Global Offset Table): 动态链接的关键组成部分,用于解析共享库函数和变量的地址。
  • .dynsym, .dynstr: 动态链接符号表和字符串表。
  • .rela.*: 重定位信息(告诉链接器/加载器如何修改代码或数据指针)。

回到 size 命令输出示例 (以 /bin/ls 为例)

$ size /bin/ls
   text    data     bss     dec     hex filename
 139304    4760    2760  146824   23d88 /bin/ls
  • text (139304 bytes): 主要包含 .text (代码指令) 和 .rodata (只读数据,如字符串常量、ls 的各种提示信息、格式字符串等)。这是程序的主体逻辑和固定字符串。
  • data (4760 bytes): 主要是 .data 段。包含 ls 命令中那些启动时就需要非零初始值的全局/静态变量。
  • bss (2760 bytes): 主要是 .bss 段。包含 ls 命令中那些未初始化或初始化为零的全局/静态变量。程序启动后,操作系统会为它在内存中分配2760字节并清零。
  • dec (146824 bytes): text + data + bss 的总和 (139304 + 4760 + 2760 = 146824)。如前所述,这不等于磁盘文件大小,也不等于运行时总内存占用,但反映了程序核心代码和静态数据的内存需求。

总结一下您的字符串在哪:

  • 函数内部的指令 (如操作字符串地址、调用 printf):.text 段。
  • 字符串常量本身 ("Hello, World!..."):.rodata 段 (在 size 的默认输出中,它的大小被合并计入 text 列)。
  • 局部非静态字符串变量 (char local_string[] = ...): 在函数被调用时,在**栈(Stack)**上分配和初始化,不属于任何这些静态段
  • 全局/静态字符串变量:
    • const char* global_str = "Constant";:指针 global_str (如果非NULL初始化) 可能在 .data.rodata,字符串 "Constant".rodata
    • char global_str[] = "Mutable";:整个字符数组 global_str 及其初始内容 "Mutable".data 段(因为它可修改)。
    • static char static_str[100];:未初始化,在 .bss 段。

希望这个结合实例的详细解释能彻底澄清各个段的含义以及您的字符串存储位置!理解这些段对于分析程序内存布局、优化大小、理解链接加载过程都至关重要。

您指出了一个需要澄清的关键点,让我给出一个绝对明确的回答:

.rodata 段在物理上独立于 .text 段,但在 size 命令的默认输出中,.rodata 的大小被合并到 text 列中显示。

准确的技术解释:

  1. 在 ELF 文件结构中(Linux 二进制标准格式):

    • .text.rodata两个完全独立的段(Section)
    • .text 包含 可执行代码(机器指令)
    • .rodata 包含 只读数据(字符串常量、全局常量等)
    • 它们在文件中占据不同的物理位置
  2. 在内存映射时:

    • 加载器通常将 .text.rodata 映射到同一个只读内存页
    • 两者共享 READ 权限,但 .textEXECUTE 权限而 .rodata 没有
    • 这是出于内存效率的考虑,但逻辑上仍是独立区域
  3. size 命令中的表现:

    命令 显示内容
    size (默认) text 列 = .text + .rodata + 其他只读段(如 .eh_frame
    size -A 单独显示 .text.rodata 的大小

验证示例:

创建一个包含字符串常量的程序:

// strtest.c
int main() {
    char* s = "This is a string constant";
    return 0;
}

编译:gcc strtest.c -o strtest

1. 查看默认 size 输出:

$ size strtest
   text    data     bss     dec     hex filename
   1631     600       8    2239     8bf strtest

这里的 text (1631) 包含代码+字符串常量

2. 使用详细模式查看独立段:

$ size -A strtest | grep -e .text -e .rodata
.text            1318
.rodata           256

清晰显示:

  • .text = 1318 字节(纯代码)
  • .rodata = 256 字节(字符串常量)

3. 使用 readelf 确认段独立性:

$ readelf -S strtest | grep -E '\.text|\.rodata'
  [13] .text             PROGBITS         0000000000001060
  [15] .rodata           PROGBITS         0000000000002000

输出显示:

  • .text 起始地址:0x1060
  • .rodata 起始地址:0x2000
  • 完全不同地址空间,证明是独立段

关键结论:

  1. 物理存储.rodata.text 在二进制文件中是 完全独立的段
  2. 权限差异
    • .text:可读+可执行
    • .rodata:只读不可执行
  3. size 命令行为
    • 默认输出中 text 列是 总和值
    • 要查看独立大小必须用 size -A

因此,直接回答您的问题:
.rodata 段不在 .text 段内部,它们是 ELF 文件中并列存在的独立段。但在 size 默认输出中,它们的大小被合并显示在 text 列中。


您的问题很关键!SysV 和 Berkeley 格式是 size 命令的两种不同输出风格,源于 Unix 历史上的两大分支。让我用清晰的对比解释它们的区别:


1. 起源背景

格式 起源系统 设计理念
Berkeley BSD Unix (加州大学伯克利) 简洁实用,关注核心内存段
SysV System V Unix (AT&T) 详细全面,显示所有段信息

2. 核心区别对比

特性 Berkeley 格式 (默认) SysV 格式 (-A 选项)
输出结构 单行摘要 多行详细列表
显示内容 仅显示 text/data/bss 三大类 显示 ELF 文件中所有段(sections)
段信息详细度 高度聚合 每个段单独列出
包含的段 合并显示:
• text = .text + .rodata + 其他只读段
分开显示:
• .text
• .rodata
• .data
• .bss
• .eh_frame 等
内存地址信息 不显示 显示每个段的加载地址
段属性信息 不显示 显示段的读写执行权限
总大小计算 text+data+bss 所有段大小总和
典型使用场景 快速查看核心内存占用 详细分析二进制文件结构

3. 视觉化对比示例

测试程序:编译一个简单 C 程序 gcc -o test test.c

(1) Berkeley 格式 (默认)
$ size test
   text    data     bss     dec     hex filename
   1631     600       8    2239     8bf test
  • 单行输出
  • 只显示三大类聚合值
  • 无法区分代码(.text)和只读数据(.rodata)
(2) SysV 格式 (size -A)
$ size -A test
test  :
section            size   addr
.interp             28     524
.note.gnu.property  32     552
.note.gnu.build-id  36     584
.gnu.hash           28     624
.dynsym             72     652
.dynstr             55     724
...
.text             1318    1024
.rodata            256    2342
.eh_frame         456    2598
.data              600    4096
.bss                 8    4696
...
Total             2239
  • 多段详细输出
  • 每个段单独列出(示例只显示部分)
  • 明确区分:
    • .text = 1318 字节(纯代码)
    • .rodata = 256 字节(字符串常量等)
    • .data = 600 字节(初始化变量)
    • .bss = 8 字节(未初始化数据)

4. 技术本质差异

方面 Berkeley 格式 SysV 格式
段映射 将多个段聚合到三大类:
• text = 所有只读+可执行段
严格遵循 ELF 文件的实际段结构
数据来源 读取程序头(Program Headers) 读取节头(Section Headers)
权限处理 忽略权限差异 反映实际内存权限
输出目标 给开发者快速参考 给链接器/加载器调试使用

5. 何时使用哪种格式?

  • 用 Berkeley 格式当您需要

    • 快速检查程序内存占用概况
    • 嵌入式开发中评估 ROM(text)/RAM(data+bss) 需求
    • 比较不同编译选项对核心内存的影响
  • 用 SysV 格式当您需要

    • 精确分析二进制文件结构
    • 查找体积膨胀的具体原因(如哪个段过大)
    • 确认字符串常量(.rodata)的实际大小
    • 调试链接问题或内存布局问题

关键结论

  1. 不是文件格式:SysV/Berkeley 只是 size 命令的输出显示格式,不是二进制文件本身的格式

  2. 核心区别

    • Berkeley = 聚合摘要 (只显示三大类)
    • SysV = 详细清单 (显示所有段)
  3. 对您问题的直接回答
    要准确查看 .rodata 段的大小,必须使用 SysV 格式 (size -A),因为在 Berkeley 格式中它被合并到 text 列显示。

在 Linux 工具链中,这种双格式支持是 Unix 历史兼容的遗产。现代开发者更常用 SysV 格式进行精确分析,而 Berkeley 格式因其简洁性仍被广泛使用在脚本和快速检查中。


您观察到了一个关键现象!SysV 格式和 Berkeley 格式的统计结果确实经常不一致,这涉及到 ELF 文件结构的深层原理。您的输出完美展示了这种差异,我们来详细分析原因:

差异原因解析(基于您的输出)

  1. 统计范围不同

    • Berkeley 格式:只统计加载到内存的三大核心段(text/data/bss)
      10138196(text) + 2940340(data) + 51105028(bss) = 64183564(dec)
      
    • SysV 格式:统计所有 ELF 段(包括调试信息等非加载段)
      Total 314672842
      
  2. 内存地址揭示真相
    在 SysV 输出中,注意两种类型的段:

    .text   9672808   273308520  # 有内存地址 → 会加载到内存
    .debug_info 103510263       0  # 地址为0 → 不加载到内存
    
  3. 非加载段占比巨大
    查看 SysV 输出中的调试段:

    .debug_info      103,510,263
    .debug_line       65,702,541
    .debug_str        30,858,998
    .debug_abbrev      4,360,002
    .debug_loclists   27,022,439
    .debug_macro      12,432,008
    

    仅这几个调试段总和就超过 244MB,而您的 ELF 文件总大小是 314MB

技术原理深度解析

ELF 文件的双层结构
ELF 文件
程序头 Program Headers
节头 Section Headers
可加载段 LOAD Segments
.text 代码
.data 数据
.bss 占位符
所有节 Sections
.text
.data
.bss
.debug_info
.comment
其他元数据
格式统计差异的本质
特性 Berkeley 格式 SysV 格式
数据源 程序头 (Program Headers) 节头 (Section Headers)
统计目标 内存加载段 所有 ELF 节
包含内容 仅运行需要的部分 包含调试信息等非运行数据
典型用途 评估运行时内存占用 分析磁盘文件组成

在您输出中的具体验证

  1. 计算加载段大小
    从 SysV 输出中筛选有非零地址的段:

    .boot_struct       16
    .boot_text_flash   24760
    .boot_data_flash   916
    ...(省略)...
    .text           9672808
    .rodata             352
    .data                 4
    .bss                  0
    .framebuffer   1382400
    ...(省略)...
    

    手动求和 ≈ 64MB(接近 Berkeley 的 64,183,564 字节)

  2. 验证调试段大小

    .debug_info      103510263
    .debug_line       65702541
    .debug_str        30858998
    ...(其他调试段)...
    

    总和 ≈ 314672842 - 64183564 ≈ 250MB

为什么设计成这样?

  1. Berkeley 格式的实际用途

    • 嵌入式开发评估 ROM/RAM 需求
    • 预测程序运行时静态内存占用
    • 快速检查:text(Flash) vs data+bss(RAM)
  2. SysV 格式的实际用途

    • 分析 ELF 文件组成结构
    • 检查调试信息大小(可 strip 掉)
    • 验证链接脚本是否正确合并段
    • 诊断 “为什么我的 ELF 文件这么大?”

专业建议

  1. 需要评估运行时内存时

    # 最佳实践:使用 readelf 查看 LOAD 段
    readelf -l vela_ap.elf | grep -A1 LOAD
    
    # 输出示例:
    LOAD           0x000000 0x08000000 0x08000000 0x36e084 0x36e084 R E 0x10000
    LOAD           0x370000 0x08000000 0x08000000 0x00000 0x15c68 RW  0x10000
    

    FileSiz 列显示实际加载大小

  2. 需要减小磁盘空间时

    # 剥离调试信息(生产环境推荐)
    strip --strip-all vela_ap.elf -o vela_ap_stripped.elf
    
    # 检查剥离后大小
    size vela_ap_stripped.elf
    
  3. 理解内存映射

    # 生成内存占用图
    arm-none-eabi-nm -S --size-sort vela_ap.elf > memory_map.txt
    

结论

您的观察完全正确:SysV 和 Berkeley 格式的统计结果不一致是正常且预期的行为,因为它们:

  1. 统计的数据源不同(程序头 vs 节头)
  2. 服务不同目的(运行时内存评估 vs 文件结构分析)
  3. 包含内容不同(仅加载段 vs 所有段)

简单记忆法

  • size → 我要烧录到设备需要多少 FLASH/RAM
  • size -A → 为什么我的 ELF 文件这么大

网站公告

今日签到

点亮在社区的每一天
去签到