Skip to main content
add re preprocess / assembly list
Source Link

Edit 2: Using Sudar's Arduino Makefile probably is the best starting point for looking at source code that has been pre-processed, or that has been compiled (into assembly language). This makefile system is fairly easy to install and use.

When you have the makefile system installed and working, you can generate pre-processed code (code that's been run through the pre-processor to incorporate #include files and to expand macros) by adding the following line within a makefile:

CPPFLAGS += -E

The -E switch tells avr-gcc to stop after preprocessing. According to man gcc its effect is:

Stop after the preprocessing stage; do not run the compiler proper. The output is in the form of preprocessed source code, which is sent to the standard output.

To generate assembly language, add the following line within a makefile:

CPPFLAGS += -S

The -S switch tells avr-gcc to stop after compiling. According to man gcc its effect is:

Stop after the stage of compilation proper; do not assemble. The output is in the form of an assembler code file for each non-assembler input file specified. ... By default, the assembler file name for a source file is made by replacing the suffix .c, .i, etc., with .s.

If you are skilled at makefile writing, it may be possible to add a target with rules to generate assembly or pre-processed code for inspection. Actually, Sudar's Arduino Makefile appears to have assembly-listing targets and rules already (as below for .pde; others for .ino and .cpp) although I haven't gotten them to work:

# generated assembly
$(OBJDIR)/%.s: %.pde $(COMMON_DEPS) | $(OBJDIR)
        @$(MKDIR) $(dir $@)
        $(CXX) -x c++ -include $(ARDUINO_HEADER) -MMD -S -fverbose-asm $(CPPFLAGS) $(CXXFLAGS) $< -o $@

[I now see that Edgar Bonet has mentioned this too.]


Edit 2: Using Sudar's Arduino Makefile probably is the best starting point for looking at source code that has been pre-processed, or that has been compiled (into assembly language). This makefile system is fairly easy to install and use.

When you have the makefile system installed and working, you can generate pre-processed code (code that's been run through the pre-processor to incorporate #include files and to expand macros) by adding the following line within a makefile:

CPPFLAGS += -E

The -E switch tells avr-gcc to stop after preprocessing. According to man gcc its effect is:

Stop after the preprocessing stage; do not run the compiler proper. The output is in the form of preprocessed source code, which is sent to the standard output.

To generate assembly language, add the following line within a makefile:

CPPFLAGS += -S

The -S switch tells avr-gcc to stop after compiling. According to man gcc its effect is:

Stop after the stage of compilation proper; do not assemble. The output is in the form of an assembler code file for each non-assembler input file specified. ... By default, the assembler file name for a source file is made by replacing the suffix .c, .i, etc., with .s.

If you are skilled at makefile writing, it may be possible to add a target with rules to generate assembly or pre-processed code for inspection. Actually, Sudar's Arduino Makefile appears to have assembly-listing targets and rules already (as below for .pde; others for .ino and .cpp) although I haven't gotten them to work:

# generated assembly
$(OBJDIR)/%.s: %.pde $(COMMON_DEPS) | $(OBJDIR)
        @$(MKDIR) $(dir $@)
        $(CXX) -x c++ -include $(ARDUINO_HEADER) -MMD -S -fverbose-asm $(CPPFLAGS) $(CXXFLAGS) $< -o $@

[I now see that Edgar Bonet has mentioned this too.]

Source Link

One method I've used for creating assembly listings for Arduino sketches when using the Arduino IDE is as follows:
• Click Verify to compile the sketch
• Locate the the temporary build directory
• Use avr-objdump with -CSI... switches to decode the ELF file

Here are some commands you can put into a shell file to automate that procedure, on a Linux system:

item=*.ino
[ -z "$item" ] && echo ino file not found && exit
BDIR=/tmp/$(ls -t /tmp | egrep -m1 build.*tmp)
BASE=$(basename $item .ino)
avr-objdump -CSI$PWD $BDIR/$BASE.cpp.elf > $BASE.ino.asm

The above assumes the current working directory (ie, $PWD) is the directory with the sketch in it; variable item is the sketch name; variable BASE is the basename of the sketch, with .ino stripped off; $BDIR is the most-recently-used temporary build directory (which, on Ubuntu Linux systems, has a path that starts with /tmp/build); and the resulting deassembly is placed in $BASE.ino.asm for viewing.

To try this manually, as you may need to do on systems where the above shell commands don't work, say

avr-objdump -CSIddd bbb/sss.cpp.elf > sss.ino.asm

in a shell or at a command console, replacing ddd with the sketch's source directory name; bbb with the temporary build directory's name; and sss with the sketch's name.