Introducing AVRDisassembler: a .NET Core (cross platform) AVR / Arduino Disassembler

AVRDisassembler is a new open source, cross platform (Windows, Mac, Linux) disassembler for the AVR microcontroller platform, written in C# (.NET Core). It supports the full instruction set as described by the ATMEL 0856 Instruction Set Documentation. The code is made available under the MIT license.

Note: Full source code for the disassembler can be found on GitHub: AVRDisassembler.

AVRDisassembler

Command line usage

Using the disassembler is very straightforward. Invoke it from the command line without arguments to get its usage documented:

AVRDisassembler 0.1.0

ERROR(S):
  Required option 'i, input' is missing.

  -i, --input    Required. Input file (HEX) to be disassembled.

  --json         (Default: false) Format output as JSON.

  --help         Display this help screen.

  --version      Display version information.

Sample output:

...
0FE4:   50-93-2B-02     sts 0x022b, r21       ; Store Direct to Data Space
0FE8:   40-93-2A-02     sts 0x022a, r20       ; Store Direct to Data Space
0FEC:   F9-01           movw r30, r18         ; Copy Register Word
0FEE:   E6-56           subi r30, 0x66        ; Subtract Immediate
0FF0:   FF-4F           sbci r31, 0xff        ; Subtract Immediate with Carry SBI
0FF2:   24-91           lpm r18, Z            ; Load Program Memory
0FF4:   20-93-29-02     sts 0x0229, r18       ; Store Direct to Data Space
0FF8:   31-2C           mov r3, r1            ; Copy Register
0FFA:   53-C0           rjmp .+166            ; Relative Jump
0FFC:   10-92-80-00     sts 0x0080, r1        ; Store Direct to Data Space
1000:   10-92-81-00     sts 0x0081, r1        ; Store Direct to Data Space
1004:   90-91-81-00     lds r25, 0x0081       ; Load Direct from Data Space (32-bit)
1008:   98-60           ori r25, 0x08         ; Logical OR with Immediate
100A:   90-93-81-00     sts 0x0081, r25       ; Store Direct to Data Space
100E:   90-91-81-00     lds r25, 0x0081       ; Load Direct from Data Space (32-bit)
1012:   91-60           ori r25, 0x01         ; Logical OR with Immediate
1014:   90-93-81-00     sts 0x0081, r25       ; Store Direct to Data Space
1018:   28-2F           mov r18, r24          ; Copy Register
101A:   30-E0           ldi r19, 0x00         ; Load Immediate
101C:   F9-01           movw r30, r18         ; Copy Register Word
101E:   E2-55           subi r30, 0x52        ; Subtract Immediate
1020:   FF-4F           sbci r31, 0xff        ; Subtract Immediate with Carry SBI
1022:   E4-91           lpm r30, Z            ; Load Program Memory
1024:   F0-E0           ldi r31, 0x00         ; Load Immediate
1026:   EE-0F           add r30, r30          ; Add without Carry
1028:   FF-1F           adc r31, r31          ; Add with Carry
102A:   E4-53           subi r30, 0x34        ; Subtract Immediate
102C:   FF-4F           sbci r31, 0xff        ; Subtract Immediate with Carry SBI
102E:   45-91           lpm r20, Z+           ; Load Program Memory
1030:   54-91           lpm r21, Z            ; Load Program Memory
1032:   50-93-24-02     sts 0x0224, r21       ; Store Direct to Data Space
1036:   40-93-23-02     sts 0x0223, r20       ; Store Direct to Data Space
103A:   F9-01           movw r30, r18         ; Copy Register Word
103C:   E6-56           subi r30, 0x66        ; Subtract Immediate
103E:   FF-4F           sbci r31, 0xff        ; Subtract Immediate with Carry SBI
1040:   24-91           lpm r18, Z            ; Load Program Memory
1042:   20-93-22-02     sts 0x0222, r18       ; Store Direct to Data Space
...

The fine print

  • Only raw HEX files are supported. It would be great to build ELF support, as we could then also support fancy source / debug information interleaving.
  • There is a nuget package for .NET style integration. Since it’s the first release, it is marked as prerelease.
  • Other languages may consume the JSON output and use that as a building block.
  • The disassembler assumes a non reduced / non “brain dead” core (e.g. no LDS16 instruction usage).
  • When multiple instructions are viable (synonyms), the disassembler will simply pick the “first” out of it’s internal matching options (this should be made configurable in some way).