My source files are *.ino, but after compilation there aren't any other files placed in the folder. Does the compiler generate intermediate assembler, and if so, where does it leave them? Or is the machine code available somewhere?
My source files are *.ino, but after compilation there aren't any other files placed in the folder.
Correct. The Arduino IDE performs compilation in a separate temporary directory, whose location you can see if you enable verbose compilation in the IDE options.
Does the compiler generate intermediate assembler, and if so, where does it leave them?
By default GCC (which the Arduino IDE uses) does not leave intermediate assembly language files on disk. You must pass the
--save-temps argument to have it leave them in the current directory, or
--save-temps=obj to save them in the output directory.
Or is the machine code available somewhere?
The machine code is available in the .elf and .hex files generated in the temprary directory.
Arduino compilation is set up with link-time optimization (LTO), and the assembly files created during C compilation don't contain any assembly code - just the intermediate representation used later in the LTO stage to generate actual assembly code. We want the latter.
It so happens, rather nicely, that the very last time assembler is invoked in the entire compilation process, is to take the output from the LTO stage, and turn it into a whole-application object file.
To get at this assembly file, do the following (on Windows):
%LOCALAPPDATA%\Arduino15\packages\arduino\hardware\avr\1.8.3\platform.local.txt(create it if it doesn't exist). Add the following line
If there already is such a line there, just add the above options (to the right of
Note: If you can't find the folder, look for the following files:
programmers.txt. If you find these files in multiple locations, the one you want should be inside your home directory (i.e. not in
/usr), and should be correlated at least partially to the version of Arduino you're using (should you have multiple versions installed).
Build the sketch again.
Look for a file named
%TEMP%\cc*.ltrans.s. Each build will create a new such file. If you sort them by timestamp, the newest one is for the most recent build.
Note: The environment variables, enclosed by
% signs, are valid in the Windows dialog boxes. You can directly paste such a path into e.g. an Open or Save As... dialog box, and it'll work. Paths with globs (
*) will act as filters (IIRC).
To know which exact
cc*.s file was generated, add the verbose option to the final binary generator pass:
compiler.c.elf.extra_flags=-save-temps=obj -fverbose-asm -v
Rebuild, and copy-paste all the output from the compilation status window in Arduino to e.g. Notepad++, and search for
ar.exe. The sole line that contains
ar.exe ends with the name of this
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
How does the file look? This is a short extract, just to show that both the C source and the assembly are intermingled - and this represents exactly the binary embedded in the
.hex file and sent to the target.
.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:
This approach also works on Linux and MacOS, except that the paths are slightly different, and path expansion uses different syntax. The two files of concern still are
platform.local.txt - a file you must create, since it doesn't exist at first, and the