📄 dpic.cpp
字号:
//=====================================================================================
//
// 模块: 反汇编PIC16C5X
//
// 版本: 1.00
//
// 日期: 2007-07-10
//
// 作者: 施探宇
//
// 说明: dpic -n rom.bin src.asm
//
//=====================================================================================
#include "stdafx.h"
// 保存标号个数
#define MAX_LABELS 256
// 代码地址上限
#define MAX_ADDRESS 0x400
// 最长代码字节(字节对齐)
#define CODE_MAX_BYTES 4
// 普通代码长度(字节对齐)
#define CODE_BYTES 2
// 代码位数(实际指令位数)
#define CODE_BITS 12
// 专用指令识别码
#define CODE_GOTO_ID 0x0a00
#define CODE_CALL_ID 0x0900
// 状态寄存器地址
#define REG_STATUS_ID 0x03
// 长整型,所有指令都要改长,这样改成别语言就方便;
typedef unsigned long UINT64;
typedef unsigned int UINT32;
typedef unsigned short UINT16;
typedef unsigned char UINT8;
typedef unsigned char BYTE;
//-----------------------------------------------------------------------------------
// 列表
//-----------------------------------------------------------------------------------
typedef struct tagDASM
{
// 代码值
UINT64 CodeData;
// 代码位
UINT64 CodeMask;
// 寄存器位
UINT64 RegsMask;
// 比特位
UINT64 BitsMask;
// 数据位
UINT64 DataMask;
// 输出格式
_TCHAR *pCodeFmt;
}DASM_TBL;
//-----------------------------------------------------------------------------------
// 代码转换有优先顺序:格式为 printf("CODE %S,%S,%S",REG,BIT,DAT)
//-----------------------------------------------------------------------------------
// PIC指令有方向指令,ADDWF 0x06,W,ADDWF 0x05,F
// 共32调指令.
DASM_TBL tblCode[]=
{
// CODE-ID CO-MASK RG-MASK BI-MASK DA-MASK FORMAT
// 没有操作数,(5)
{ 0x0000, 0x0fff, 0x0000, 0x0000, 0x0000, _T("NOP")},
{ 0x0002, 0x0fff, 0x0000, 0x0000, 0x0000, _T("OPTION")},
{ 0x0003, 0x0fff, 0x0000, 0x0000, 0x0000, _T("SLEEP")},
{ 0x0004, 0x0fff, 0x0000, 0x0000, 0x0000, _T("CLRWDT")},
{ 0x0040, 0x0fff, 0x0000, 0x0000, 0x0000, _T("CLRW")},
// 单操作数,不指定方向(3)
{ 0x0000, 0x0ff8, 0x0007, 0x0000, 0x0007, _T("TRIS %s")},
{ 0x0020, 0x0fe0, 0x001f, 0x0000, 0x0000, _T("MOVWF %s")},
{ 0x0060, 0x0fe0, 0x001f, 0x0000, 0x0000, _T("CLRF %s")},
// 单操作数,需指定方向(13)
{ 0x0080, 0x0fc0, 0x001f, 0x0020, 0x0000, _T("SUBWF %s,%s")},
{ 0x00c0, 0x0fc0, 0x001f, 0x0020, 0x0000, _T("DECF %s,%s")},
{ 0x0100, 0x0fc0, 0x001f, 0x0020, 0x0000, _T("IORWF %s,%s")},
{ 0x0140, 0x0fc0, 0x001f, 0x0020, 0x0000, _T("ANDWF %s,%s")},
{ 0x01c0, 0x0fc0, 0x001f, 0x0020, 0x0000, _T("ADDWF %s,%s")},
{ 0x0200, 0x0fc0, 0x001f, 0x0020, 0x0000, _T("MOVF %s,%s")},
{ 0x0260, 0x0fc0, 0x001f, 0x0020, 0x0000, _T("COMF %s,%s")},
{ 0x0280, 0x0fc0, 0x001f, 0x0020, 0x0000, _T("INCF %s,%s")},
{ 0x02c0, 0x0fc0, 0x001f, 0x0020, 0x0000, _T("DECFSZ %s,%s")},
{ 0x0300, 0x0fc0, 0x001f, 0x0020, 0x0000, _T("RRF %s,%s")},
{ 0x0340, 0x0fc0, 0x001f, 0x0020, 0x0000, _T("RLF %s,%s")},
{ 0x0380, 0x0fc0, 0x001f, 0x0020, 0x0000, _T("SWAPF %s,%s")},
{ 0x03c0, 0x0fc0, 0x001f, 0x0020, 0x0000, _T("INCFSZ %s,%s")},
// 位操作,双操作数(4)
{ 0x0400, 0x0f00, 0x001f, 0x00e0, 0x0000, _T("BCF %s,%s")},
{ 0x0500, 0x0f00, 0x001f, 0x00e0, 0x0000, _T("BSF %s,%s")},
{ 0x0600, 0x0f00, 0x001f, 0x00e0, 0x0000, _T("BTFSC %s,%s")},
{ 0x0700, 0x0f00, 0x001f, 0x00e0, 0x0000, _T("BTFSS %s,%s")},
// 立即数操作,单操作数(7)
{ 0x0800, 0x0f00, 0x0000, 0x0000, 0x00ff, _T("RETLW %s")},
{ 0x0900, 0x0f00, 0x0000, 0x0000, 0x00ff, _T("CALL %s")},
{ 0x0a00, 0x0e00, 0x0000, 0x0000, 0x01ff, _T("GOTO %s")},
{ 0x0d00, 0x0f00, 0x0000, 0x0000, 0x00ff, _T("IORLW %s")},
{ 0x0c00, 0x0f00, 0x0000, 0x0000, 0x00ff, _T("MOVLW %s")},
{ 0x0e00, 0x0f00, 0x0000, 0x0000, 0x00ff, _T("ANDLW %s")},
{ 0x0f00, 0x0f00, 0x0000, 0x0000, 0x00ff, _T("XORLW %s")},
};
//-----------------------------------------------------------------------------------
// 寄存器名称
//-----------------------------------------------------------------------------------
_TCHAR *arrRegs[]=
{
/*0x00*/ _T("INDF"),
/*0x01*/ _T("TMR0"),
/*0x02*/ _T("PCL"),
/*0x03*/ _T("STATUS"),
/*0x04*/ _T("FSR"),
/*0x05*/ _T("PORTA"),
/*0x06*/ _T("PORTB"),
/*0x07*/ _T("PORTC"),
};
//-----------------------------------------------------------------------------------
// 状态位
//-----------------------------------------------------------------------------------
_TCHAR *arrStatus[]=
{
/*0x00*/ _T("C"),
/*0x01*/ _T("DC"),
/*0x02*/ _T("Z"),
/*0x03*/ _T("P"),
/*0x04*/ _T("T"),
/*0x05*/ _T("GP0"),
/*0x06*/ _T("GP1"),
/*0x07*/ _T("RST"),
};
//-----------------------------------------------------------------------------------
// 默认文件名称
//-----------------------------------------------------------------------------------
_TCHAR *pStart = _T("");
_TCHAR *pBinFile = _T("rom.bin");
_TCHAR *pSrcFile = _T("src.asm");
_TCHAR buff[]=_T("0x0000");
// 文件指针
FILE *fpBin;
FILE *fpSrc;
// 默认起始地址:
int iCodeStart = 0;
// 参数序号
int idArgv = 1;
// 指令缓冲区
BYTE pCodeBuff[CODE_MAX_BYTES];
// 存储标号和函数地址
UINT64 useLabels[MAX_LABELS];
UINT64 posLabels = 0;
// 显示帮助
void ShowHelp();
// 状态名
_TCHAR *GetStatuName(UINT64 nBits);
// 寄存器名
_TCHAR *GetRegname(UINT64 nReg);
// 登记标号
int Preparse(UINT64 lCode);
// 代码分析
int ParseCode(UINT64 lLine,UINT64 lCode,FILE *fpOut);
// 查找已登记标号
int FindLabel(UINT64 lLine);
// 文件分析
int ParseFile(int iStart, FILE *pIn,FILE *pOut);
//=====================================================================================
// 开始函数
//=====================================================================================
int main(int argc, _TCHAR* argv[])
{
// 判断参数
if(argc < 2 || argc > 4)
{
ShowHelp();
#ifdef _DEBUG
getchar();
#endif
return -1;
}
// 默认指向第一个参数
idArgv = 1;
pStart = argv[idArgv];
// 是否有地址参数?
if(pStart[0] == '-')
{
iCodeStart = atoi(&pStart[1]);
idArgv ++;
}
if(argc > idArgv )
{
pBinFile = argv[idArgv ];
}
if(argc > idArgv + 1)
{
pSrcFile = argv[idArgv +1];
}
fpBin = fopen(pBinFile,"rb");
if(!fpBin)
{
printf("Can't open bin file: %s!\n",pBinFile);
#ifdef _DEBUG
getchar();
#endif
return -1;
}
fpSrc = fopen(pSrcFile,"w+a");
if(!fpSrc)
{
fclose(fpBin);
printf("Can open src file: %s!\n",pSrcFile);
#ifdef _DEBUG
getchar();
#endif
return -1;
}
// 显示抬头
printf(_T(" PIC16C5X DISASM TOOLS(C) Version 1.00\n"));
printf(_T("---------------------------------------------------------------\n"));
printf(_T(" Code start: %x.\n"),iCodeStart);
printf(_T(" Input file: %s.\n"),pBinFile);
printf(_T(" Output file: %s.\n"),pSrcFile);
printf(_T("---------------------------------------------------------------\n"));
printf(_T(" QQ:190376601,TEL:13751152175 --Aleck.Shi\n"));
// 分析文件
ParseFile(iCodeStart,fpBin,fpSrc);
fclose(fpBin);
fclose(fpSrc);
// 处理完毕!
printf(_T(" Processed done!\n"));
#ifdef _DEBUG
getchar();
#endif
return 0;
}
//=====================================================================================
// 显示帮助
//=====================================================================================
void ShowHelp()
{
printf(_T(" PIC16C5X DISASM TOOLS(C) Version:1.00\n"));
printf(_T("---------------------------------------------------------------\n"));
printf(_T(" usage:dpic [-code address] <bin file> [src file]\n"));
printf(_T(" exp:dpic rom.bin\n"));
printf(_T(" dpic -2 rom.bin\n"));
printf(_T(" dpic -10 rom.bin src.asm\n"));
printf(_T("---------------------------------------------------------------\n"));
printf(_T(" QQ:190376601,TEL:13751152175 ----Aleck.Shi\n"));
}
//=====================================================================================
// 文件分析
//=====================================================================================
int ParseFile(int iStart, FILE *fpIn,FILE *fpOut)
{
UINT64 lCodePos = 0;
UINT64 lCode = 0;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -