【问题标题】:How can I get an assembly language listing of my Arduino Sketches on Windows?如何在 Windows 上获得我的 Arduino 草图的汇编语言列表?
【发布时间】:2010-10-29 12:28:11
【问题描述】:

我希望能够看到我的 Arduino 草图的汇编语言列表。我怎样才能做到这一点?

更新:我正在 Windows 机器上运行 Arduino 软件。

【问题讨论】:

    标签: windows assembly arduino


    【解决方案1】:

    如果你使用Linux,可以关注this tutorial on how to compile for the Arduino without the IDE

    一旦你这样做了,你可以通过运行带有 -s 标志的 gcc 来获得一个程序集列表。

    【讨论】:

    • @Magnus 我在 Windows 上运行,但该链接可能仍然有用 - 我会看看。谢谢。
    【解决方案2】:

    以下(hacky)步骤将提供 Arduino 草图和 Windows 上相关库的汇编语言列表:

    1. 下载(并重命名)Arduino Windows command line batch files 到包含您的草图的目录(.pde 文件)
    2. 按照上述链接页面中的说明设置所需的环境变量
    3. -S 添加到abuild.bat 中的abuild_gcc_opts 变量(第158 行)
    4. 运行abuild -r -c <pde_filename>
    5. 预计会收到以下警告和错误,您可以忽略:

      ... 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

    汇编语言列表可以在创建的obj 目录中的.o 文件中找到。例如,草图本身的清单在obj\<pde_filename>.cpp.o

    【讨论】:

      【解决方案3】:

      一种方法是在构建创建的.elf 文件上使用avr-objdump。例如,在 OS X 上我可以这样做:

      $ cd ~/arduino-0015/examples/Digital/Blink/applet
      $ avr-objdump -d Blink.elf
      

      (显然,您在 Windows 上的路径可能不同。)这会产生代码的反汇编,其中一部分看起来像这样:

      0000013a :
       13a: 0e 94 3e 01 调用 0x27c 
       13e: 0e 94 97 00 调用 0x12e 
       142: 0e 94 80 00 调用 0x100 
       146: fd cf rjmp .-6 ; 0x142 
      

      【讨论】:

      【解决方案4】:

      -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>
      ...
      

      【讨论】:

        【解决方案5】:

        Arduino 编译使用链接时间优化 (LTO) 设置,在 C 编译期间创建的汇编文件不包含任何汇编代码 - 只是稍后在 LTO 阶段用于生成实际汇编代码的中间表示。我们想要后者。

        恰巧,在整个编译过程中最后一次调用汇编程序是从 LTO 阶段获取输出,并将其转换为整个应用程序的目标文件。

        要获取此程序集文件,请执行以下操作:

        1. 打开%LOCALAPPDATA%\Arduino15\packages\arduino\hardware\avr\1.8.3\platform.local.txt(如果不存在则创建它)。添加以下行

          compiler.c.elf.extra_flags=-save-temps=obj -fverbose-asm
          

          如果那里已经有这样的一行,只需添加上述选项(在=的右侧)。

          注意:如果找不到文件夹,请查找以下文件:boards.txtplatform.txtprogrammers.txt。如果您在多个位置找到这些文件,那么您想要的文件应该在您的主目录中(即不在Program Files/Applications/usr 中),并且应该至少部分相关到您正在使用的 Arduino 版本(如果您安装了多个版本)。

        2. 再次构建草图。

        3. 查找名为 %TEMP%\cc*.ltrans.s 的文件。每个构建都将创建一个新的此类文件。如果您按时间戳对它们进行排序,则最新的是最新版本。

        注意:% 符号括起来的环境变量在Windows 对话框中有效。您可以直接将这样的路径粘贴到例如打开或另存为...对话框,它将起作用。带有 glob (*) 的路径将充当过滤器 (IIRC)。

        要知道生成了哪个确切的cc*.s 文件,请将详细选项添加到最终的二进制生成器通道:

        compiler.c.elf.extra_flags=-save-temps=obj -fverbose-asm -v
        

        重新构建,并将 Arduino 中编译状态窗口中的所有输出复制粘贴到 e.g.记事本++,然后搜索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 文件。

        【讨论】:

          猜你喜欢
          • 2013-07-24
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-05-03
          • 2013-10-29
          • 1970-01-01
          • 1970-01-01
          • 2015-12-15
          相关资源
          最近更新 更多