Arduino vs. embedded C - AVR reversing
As I was teaching some embedded C basics, I was asked what are some benefits of embedded C over the classic Arduino language for an Arduino-based board. This article tries to see what we can do by reversing a really simple program compiled with both methods for the Arduino Uno.
arduino-cli: Command Line Interface for Arduino
- AVR cross compiler:
sudo apt install gcc-avr
- Optional: an Arduino simulator such as SimulIDE
We want to create the most simple program which goal is to light on the built-in LED, located at port 13 (or PORT PB5) on the Arduino Uno.
Codes and compilation
|Storage use||724 bytes||144 bytes|
The embedded C code is 5 times smaller than the Arduino one which is a bit “weird” as both codes do the same thing! Let’s find why by reversing binaries and analyzing assembly codes.
arduino-cli produces the
*.elf binary and the
*.hex file which is just a series of bytes to be loaded in the Arduino.
Here is a part of the Arduino objdump. The assembly code is really long for such a program… It is easy to understand when we look at the source code of
digitalWrite() (https://github.com/arduino/ArduinoCore-avr/blob/master/cores/arduino/wiring_digital.c). It does not only write a value into a register…
Garretlab made an analysis of both functions:
Embedded C binary
At first sight, it’s clearly easier. Step-by-step instruction decoding:
ldi r24, 0x20: according to the AVR ISA ,
ldi load the value
r24 which is a General Purpose Working Register of the Arduino.
out 0x04, r24: this instruction write the value stored in
r24 at the address
0x04 (the address of
DDRB according to ).
DDRB5 is set to 1 😉
out 0x05, r24: same thing, for
Embedded C code is usually quicker and smaller as long as we make some effort to study the datasheet. But it’s worth it when we’re working with embedded systems! 😉