为什么 objdump 生成的程序集很大?
Why assembly produced by objdump is huge?
我正在尝试查看我的简单 C 应用程序的程序集。因此,我尝试使用 objdump
从二进制生成程序集,它生成了大约 4.3MB 大小的文件,其中包含 103228 行汇编代码。然后,我尝试通过向 gcc
提供 -S
& -save-temps
标志来做到这一点。
我用过以下三个命令:
1. arm-linux-gnueabi-objdump -d hello_simple > hello_simple.dump
2. arm-linux-gnueabi-gcc -save-temps -static hello_simple.c -o hello_simple -lm
3. arm-linux-gnueabi-gcc -S -static hello_simple.c -o hello_simple.asm -lm
在 2 和 3 的情况下,产生完全相同的结果,即 65 行汇编代码。我知道 objdump
也会产生一些额外的细节。
但是,为什么会有巨大的差异呢?
EDIT1: 我使用了以下命令来构建该二进制文件:
arm-linux-gnueabi-gcc -static hello_simple.c -o hello_simple -lm
EDIT2: 虽然,-static
和 -lm
标志在这里可能看起来没有必要,但是,我必须在编译时添加后在模拟器上执行这个二进制文件一些装配组件,使它们成为必须。
那么,在分析执行轨迹时,我应该考虑哪些汇编代码最相关? (我知道这是另一个问题,但在同一个答案中涵盖它会很方便。)
后两个只是为您的函数保存 asm。
第一个也有CRT启动代码。而且,由于您静态链接它,所以您调用的所有库函数。
请注意,对于 3,-static
和 -lm
什么都不做,因为您没有链接。 gcc foo.c -S -O3 -fverbose-asm -o- | less
通常很方便。
我注意到 none 的命令行包含 -O3
或 -march=
。您应该在优化的情况下进行编译,并让 gcc 针对目标硬件优化您的代码。
.s
是机器生成的asm的标准后缀。 (.S
对于手写的 asm:gcc foo.S 将首先通过 cpp 运行 它)。 gcc -S
生成 .s
,与 -c
生成 .o
.
的方式相同
对于 x86,.asm
通常仅用于 Intel 语法 (NASM/YASM),但我不知道 ARM 的约定是什么。
So, which assembly code should I consider as the most relevant during my analysis of execution traces?
这取决于你想学什么!如果您对每个库函数调用的方式有很好的了解(在指令数、分支预测器污染分支数和数据缓存污染方面),那么您不需要跟踪通过库调用执行。如果您有一些内部循环使用的数学库函数,那么如果代码是时间关键的,那么值得查看它们。
不过,通常情况下,分析器或调试器中的单步执行对此很有用。仅具有大量库代码的反汇编输出通常只是混乱。
我正在尝试查看我的简单 C 应用程序的程序集。因此,我尝试使用 objdump
从二进制生成程序集,它生成了大约 4.3MB 大小的文件,其中包含 103228 行汇编代码。然后,我尝试通过向 gcc
提供 -S
& -save-temps
标志来做到这一点。
我用过以下三个命令:
1. arm-linux-gnueabi-objdump -d hello_simple > hello_simple.dump
2. arm-linux-gnueabi-gcc -save-temps -static hello_simple.c -o hello_simple -lm
3. arm-linux-gnueabi-gcc -S -static hello_simple.c -o hello_simple.asm -lm
在 2 和 3 的情况下,产生完全相同的结果,即 65 行汇编代码。我知道 objdump
也会产生一些额外的细节。
但是,为什么会有巨大的差异呢?
EDIT1: 我使用了以下命令来构建该二进制文件:
arm-linux-gnueabi-gcc -static hello_simple.c -o hello_simple -lm
EDIT2: 虽然,-static
和 -lm
标志在这里可能看起来没有必要,但是,我必须在编译时添加后在模拟器上执行这个二进制文件一些装配组件,使它们成为必须。
那么,在分析执行轨迹时,我应该考虑哪些汇编代码最相关? (我知道这是另一个问题,但在同一个答案中涵盖它会很方便。)
后两个只是为您的函数保存 asm。
第一个也有CRT启动代码。而且,由于您静态链接它,所以您调用的所有库函数。
请注意,对于 3,-static
和 -lm
什么都不做,因为您没有链接。 gcc foo.c -S -O3 -fverbose-asm -o- | less
通常很方便。
我注意到 none 的命令行包含 -O3
或 -march=
。您应该在优化的情况下进行编译,并让 gcc 针对目标硬件优化您的代码。
.s
是机器生成的asm的标准后缀。 (.S
对于手写的 asm:gcc foo.S 将首先通过 cpp 运行 它)。 gcc -S
生成 .s
,与 -c
生成 .o
.
对于 x86,.asm
通常仅用于 Intel 语法 (NASM/YASM),但我不知道 ARM 的约定是什么。
So, which assembly code should I consider as the most relevant during my analysis of execution traces?
这取决于你想学什么!如果您对每个库函数调用的方式有很好的了解(在指令数、分支预测器污染分支数和数据缓存污染方面),那么您不需要跟踪通过库调用执行。如果您有一些内部循环使用的数学库函数,那么如果代码是时间关键的,那么值得查看它们。
不过,通常情况下,分析器或调试器中的单步执行对此很有用。仅具有大量库代码的反汇编输出通常只是混乱。