Arduino Due vs. embedded C - ARM reversing
arduino-cli: Command Line Interface for Arduino
- ARM cross compiler:
sudo apt install gcc-arm-none-eabi
We want to create the most simple program which goal is to light on the built-in LED, located at port PB27 on the Arduino Due.
Codes and compilation
|Storage use||10660 bytes||2544 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-sam/blob/master/cores/arduino/wiring_digital.c). It does not only write a value into a register…
Embedded C binary
At first sight, it’s clearly easier. Step-by-step instruction decoding using mainly  and :
- mov.w r2, #134217728. Move the immediate value
r2, a general purpose register.
0b1000000000000000000000000000(bin) which is 1 on the 27th bit ! 😉
- str r2, [r3, #0]. Store the value of
r3, another general purpose register, with offset=0. According to the register mapping:
PIO_PERis at the offset
- str r2, [r3, #16]. Store the value of
r3with offset=16 (or
0x10in hexadecimal). According to the register mapping:
PIO_OERis at the offset
- mov.w r2, #4294967295. Move the immediate value
4294967295in register 2.
0xFFFFFFFF(hex). In this case, we put all bits to 1. It doesn’t really matter as only the 27th has been enabled 😉
- str r2, [r3, #56]. Store the value of
r3with offset=56 (or
0x38in hexadecimal). According to the register mapping:
PIO_ODSRis at the offset
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! 😉