An Assembler / disassembler for Pic18 microcontrollers
The name is light-hearted; 'disPicable' meaning its a disassembler for PIC MCUs, 'Mpdasmasm' meaning Microchip Disassembler-Assembler
The main issue with the MPLAB diassembler, and other projects, is that they do not produce usable code. This is due to a number of reasons
-
Hard coded addresses for branching instructions
-
Aliasing of data bytes with instructions which produces non-sense code
-
Double word instructions produce redundant NOP instructions for the second word
-
Disassemble a PIC hex file into a functional and readable .asm file
-
Reassemble the same file with or without modifications into a usable hex file
-
Add symbolic labels for branching/Call instructions. Otherwise any modification will break the program
-
Add symbolic labels for TBLRD instructions. for the same reason as above
-
Frequently table read address are passed as arguments to functions, which can make tracking them difficult. It's necessary to do this, so that we can differentiate between data and code
-
Another issue, is that sometimes a program will read the entire program memory (for example, after an update) for verification, which adds another layer of ambiguity
-
I'm trying to limit the amount of hard-coding and external resources needed. currently the program can (optionally) read in a ".inc" file for whatever the target processor is. This file mostly contains information on the chip's SFRs (special function registers), it doesn't really give any information on the chip, only the number of RAM banks and whether EEPROM is present
Symbolic labels work for Branch/Call instruction, but not table reads. although the data being read by the table read is indicated in line with the instruction
Apart from decoding instructions, the program will also
The displayed values are in hex and ascii
This can be helpful for quickly estimating the purpose of a function
It works by monitoring the use of software stacks (i.e. POSTINCx SFRs). If the code uses other registers for passing arguments, this is not detected
If the function being called uses any SFRs, this will also be indicated
You can see here that the function must be transmitting '\r' over UART (TXREG)
A header will appear above each function indicating which registers are used
If General Purpose registers are used, then these will also be indicated under the tag "RAM"
You can see that these nonsense commands are actually ascii data '3.'
Currently this only works if the TBLRPTR is loaded with literals
The Assembler can successfully re-assemble the disassembled hex file. It can also process brand new .asm files, but is not yet fully comptaible with MPLAB's assembler.
Here's a short program that will just loop until it has finished reading a "DB" string
which generates the hex file
which can then be re-assembled into
Note - while we lost the symbolic label for the table pointer, we retained the Branching label. However the label has lost meaning and just takes the memory address that it is stored in
The program is compatible with all 75 PIC18 single and double word instructions; including with optional arguments.
It does not have support for the extended IS or triple word instructions (i.e. MOVFFL)
-
Hex notation is supported, examples 0x37, h'37
-
Decimal notation is supported, examples 0d37, d'37
-
Binary notation is supported, examples 0b1101, b'1101
Any bare number is assumed to be hexadecimal
- any number of ORG directives can be placed into the Program as so 'ORG 0x10f5'
- lables must appear on a line by themselves and contain a colon. There are no other limitations
label DB "hello"
DB "World\0"
if you want a null terminator, you need to include it in the string itself as "World\0"
this is an artifact of the disassembling process
so if you were to read "label" until TABLAT == 0, you would read "Hello World"
Limited support for C-Style Macros
#define SUM(x,y) MOVFW x, BANKSEL(x)\
ADDFW y, f, BANKSEL(y)
Including files
you will need to include a header file from the relevant microcontroller
#include 'pic18xyz.inc'
MyVar equ 0x100
The program supports inline comments using either ';' or '//'
and supports multiline comments using /* */
You can either use command line arguments to specificy files/functionality or else have the program present a prompt
To disassemble a file called "file.hex" that uses a pic18f45k50 MCU
disPicable dasm pic18f45k50.inc file.hex
To assemble a file called "file.asm" that uses a pic18f45k50 MCU
disPicable asm pic18f45k50.inc file.asm
To compare the original hex file with the reassembled one
disPicable cmp original.hex generated.hex
note: you will need to provide the ".inc" file yourself (it can be aquired from MPLAB for example)
The program will search the working directory for files that have extensions ".inc", ".hex" and ".asm". It will then ask you which ones you wish to use
The program will create a file called "DisassembledCode.asm" or "AssembledCode.hex" in the working directory
CmakeLists.txt file is provided
A tutorial can be found here https://code.visualstudio.com/docs/cpp/cmake-linux