我正在尝试查看我的简单C应用程序的程序集。因此,我尝试使用objdump
从二进制文件生成程序集,并生成大约4.3MB大小的文件,其中 103228行汇编代码。然后,我试图提供-S
& -save-temps
的{{1}}个标记。
我使用了以下三个命令:
gcc
如果是2&在图3中,产生完全相同的结果,即 65行汇编代码。我理解 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
也会产生一些额外的细节。
但是,为什么会出现巨大差异?
EDIT1:我使用以下命令构建该二进制文件:
objdump
EDIT2:虽然arm-linux-gnueabi-gcc -static hello_simple.c -o hello_simple -lm
和-static
标志可能看起来不必要但是,我必须在编译时添加一些组件组件后在模拟器上执行此二进制文件,他们是必须的。
那么,在我分析执行跟踪时,我应该考虑哪个汇编代码最相关? (我知道这是另一个问题,但在同一个答案中覆盖它会很方便。)
答案 0 :(得分:3)
后两个只是为你的功能保存asm。
第一个也有CRT启动代码。而且,由于您静态链接它,所以您调用的所有库函数。
请注意,对于3,-static
和-lm
不做任何事情,因为您没有链接。 gcc foo.c -S -O3 -fverbose-asm -o- | less
通常很方便。
我注意到您的命令行中没有一个包含-O3
或-march=
。您应该在优化时进行编译,并让gcc优化您的目标硬件代码。
.s
是机器生成的asm的标准后缀。 (.S
用于手写的asm:gcc foo.S将首先通过cpp运行它。 gcc -S
生成.s
,与-c
生成.o
的方式相同。
对于x86,.asm
通常仅用于Intel语法(NASM / YASM),但IDK用于ARM的约定。
那么,在我分析执行跟踪时,我应该考虑哪个汇编代码最相关?
这取决于你的学习内容!如果你对如何“昂贵”有很好的认识。每个库函数调用(在指令数量,污染分支预测器的分支数量和数据缓存污染方面),然后您不需要通过库调用跟踪执行。如果您有一些内部循环中使用的数学库函数,那么如果代码对时间要求严格,则值得查看它们。
通常,调试器中的探查器或单步执行对此非常有用。只是有很多库代码的反汇编输出通常只是混乱。