我希望能够看到我的Arduino草图的汇编语言列表。我怎样才能做到这一点?
更新:我正在Windows机器上运行Arduino软件。
答案 0 :(得分:13)
执行此操作的一种方法是在构建创建的avr-objdump
文件上使用.elf
。例如,在OS X上我可以这样做:
$ cd ~/arduino-0015/examples/Digital/Blink/applet $ avr-objdump -d Blink.elf
(显然,你在Windows上的路径可能会有所不同。)这会产生代码的反汇编,其中一部分看起来像这样:
0000013a <main>: 13a: 0e 94 3e 01 call 0x27c <init> 13e: 0e 94 97 00 call 0x12e <setup> 142: 0e 94 80 00 call 0x100 <loop> 146: fd cf rjmp .-6 ; 0x142 <main+0x8>
答案 1 :(得分:6)
如果您使用的是Linux,则可以关注this tutorial on how to compile for the Arduino without the IDE。
执行此操作后,您可以通过使用-s标志运行gcc来获取程序集列表。
答案 2 :(得分:3)
以下(hacky)步骤将在Windows上提供Arduino草图和相关库的汇编语言列表:
.pde
文件)-S
添加到abuild_gcc_opts
中的abuild.bat
变量(第158行)abuild -r -c <pde_filename>
期望获得以下警告和错误,您可以忽略这些错误:
... warning: #warning "This file has been moved to <util/delay.h>."
.\obj\<pde_filename>.cpp.o: file format not recognized: treating as linker script
.\obj\<pde_filename>.cpp.o:1: syntax error
可以在创建的.o
目录中的obj
文件中找到汇编语言列表。例如,草图本身的列表位于obj\<pde_filename>.cpp.o
答案 3 :(得分:0)
-S(非s)标志也显示c代码。也称为混合列表:
linux :( .arduino / preferences.txt:delete_target_folder = false)
$ cd /tmp/buildxxxx.tmp
$ avr-objdump -dS Blink.cpp.elf
int main(void)
{
init();
2f4: 8a df rcall .-236 ; 0x20a <init>
...
答案 4 :(得分:0)
Arduino 编译设置了链接时优化 (LTO),在 C 编译期间创建的汇编文件不包含任何汇编代码——只是稍后在 LTO 阶段用于生成实际汇编代码的中间表示。我们想要后者。
很巧的是,在整个编译过程中最后一次调用汇编器时,是从 LTO 阶段获取输出,并将其转换为整个应用程序的目标文件。
要获取此程序集文件,请执行以下操作:
打开 %LOCALAPPDATA%\Arduino15\packages\arduino\hardware\avr\1.8.3\platform.local.txt
(如果它不存在则创建它)。添加以下行
compiler.c.elf.extra_flags=-save-temps=obj -fverbose-asm
如果那里已经有这样的一行,只需添加上面的选项(在 =
的右侧)。
注意:如果找不到该文件夹,请查找以下文件:boards.txt
、platform.txt
、programmers.txt
。如果您在多个位置找到这些文件,您想要的文件应该在您的主目录中(即不在 Program Files
或 /Applications
或 /usr
中),并且应该至少部分地与您使用的 Arduino 版本相关(如果您安装了多个版本)。
再次构建草图。
查找名为 %TEMP%\cc*.ltrans.s
的文件。每个构建都会创建一个新的此类文件。如果您按时间戳对它们进行排序,则最新的将用于最近的构建。
注意: 用 %
符号括起来的环境变量在 Windows 对话框中有效。您可以直接将这样的路径粘贴到例如一个打开或另存为...对话框,它会起作用。带有 glob (*
) 的路径将用作过滤器 (IIRC)。
要知道生成的是哪个 cc*.s
文件,请将详细选项添加到最终的二进制生成器传递:
compiler.c.elf.extra_flags=-save-temps=obj -fverbose-asm -v
重新构建,然后将 Arduino 中编译状态窗口的所有输出复制粘贴到例如Notepad++,然后搜索 ar.exe
。包含 ar.exe
的唯一行以该 cc
文件的名称结尾:
c:/users/[...omitted...]/avr/bin/as.exe -mmcu=avr6 -mno-skip-bug
-o C:\Users\[...]\AppData\Local\Temp\cc3XhU2F.ltrans0.ltrans.o
C:\Users\[...]\AppData\Local\Temp\cc3XhU2F.ltrans0.ltrans.s
文件看起来如何?这是一个简短的摘录,只是为了表明 C 源代码和程序集是混合在一起的 - 这正是嵌入在 .hex
文件中并发送到目标的二进制文件。
.LBE33:
.LBE32:
.LBB34:
.LBB35:
; C:\Users\[...]\Documents\Arduino\sketch_jul01a\sketch_jul01a.ino:29: pinMode(ledPin, OUTPUT);
.file 4 "C:\\Users\\[...]\\Documents\\Arduino\\sketch_jul01a\\sketch_jul01a.ino"
.loc 4 29 0
ldi r22,lo8(1) ; ,
ldi r24,lo8(13) ; ,
call pinMode ;
.LVL55:
; C:\Users\[...]\Documents\Arduino\sketch_jul01a\sketch_jul01a.ino:30: pinMode(relayPin, OUTPUT);
.loc 4 30 0
ldi r22,lo8(1) ; ,
ldi r24,lo8(12) ; ,
call pinMode ;
.LVL56:
; C:\Users\[...]\Documents\Arduino\sketch_jul01a\sketch_jul01a.ino:31: pinMode(ldrPin, INPUT);
.loc 4 31 0
ldi r22,0 ;
ldi r24,lo8(54) ; ,
call pinMode ;
.LVL57:
.LBE35:
.LBE34:
.LBB36:
.LBB37:
这个方法也适用于Linux和MacOS,只是路径略有不同,路径扩展使用不同的语法。两个值得关注的文件仍然是 platform.local.txt
- 您必须创建的文件,因为它最初不存在,以及 ${TEMP}/cc*.ltrans.s
文件。