⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 eval_disasm.c

📁 C89c51 usb驱动程序,实现了usb转串口的功能,提供了一个虚拟的串口
💻 C
📖 第 1 页 / 共 2 页
字号:
	"MOV R5, A",
	"MOV R6, A",
	"MOV R7, A"
};


/*  Addressing Mode look-up-table...
 *
 *  0 = undefined opcode
 *  1 = no operands
 *  2 = one immediate operand
 *  3 = one direct operand
 *  4 = one bit-addressed operand
 *  5 = one relative address operand
 *  6 = one absolute address operand
 *  7 = two-byte immediate operand
 *  8 = two operands: direct, immediate
 *  9 = two operands: direct, direct
 * 10 = two operands: immediate, relative address
 * 11 = two operands: direct, relative address
 * 12 = two operands: bit address, relative address
 * 13 = two-byte long address operand
 */
const  uint8  kabOperandType[256] =
{
	 1, 6, 13, 1, 1,  3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0 */
	12, 6, 13, 1, 1,  3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 1 */
	12, 6,  1, 1, 2,  3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 2 */
	12, 6,  1, 1, 2,  3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 3 */
	 5, 6,  3, 8, 2,  3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 4 */
	 5, 6,  3, 8, 2,  3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 5 */
	 5, 6,  3, 8, 2,  3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 6 */
	 5, 6,  4, 1, 2,  8, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, /* 7 */
	 5, 6,  4, 1, 1,  9, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, /* 8 */
	 7, 6,  4, 1, 2,  3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 9 */
	 4, 6,  4, 1, 1,  0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, /* A */
	 4, 6,  4, 1, 10, 11, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, /* B */
	 3, 6,  4, 1, 1,  3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* C */
	 3, 6,  4, 1, 1, 11, 1, 1, 5, 5, 5, 5, 5, 5, 5, 5, /* D */
	 1, 6,  1, 1, 1,  3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* E */
	 1, 6,  1, 1, 1,  3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1  /* F */
};


const  char  * pkszSFRbitname[128] =
{
/* 80 */
	"P0.0", "P0.1", "P0.2", "P0.3", "P0.4", "P0.5", "P0.6", "P0.7",
/* 88 */
	"IT0", "IE0", "IT1", "IE1", "TR0", "TF0", "TR1", "TF1",
/* 90 */
	"P1.0", "P1.1", "P1.2", "P1.3", "P1.4", "P1.5", "P1.6", "P1.7",
/* 98 */
	"RI", "TI", "RB8", "TB8", "REN", "SM2", "SM1", "SM0",
/* A0 */
	"P2.0", "P2.1", "P2.2", "P2.3", "P2.4", "P2.5", "P2.6", "P2.7",
/* A8 */
	"EX0", "ET0", "EX1", "ET1", "ES", "0ADh", "0AEh", "EA",
/* B0 */
	"P3.0", "P3.1", "P3.2", "P3.3", "P3.4", "P3.5", "P3.6", "P3.7",
/* B8 */
	"PX0", "PT0", "PX1", "PT1", "PS", "0BDh", "0BEh", "0BFh",
/* C0 */
	"0C0h", "0C1h", "0C2h", "0C3h", "0C4h", "0C5h", "0C6h", "0C7h",
/* C8 */
	"0C8h", "0C9h", "0CAh", "0CBh", "0CCh", "0CDh", "0CEh", "0CFh",
/* D0 */
	"P", "0D1h", "OV", "RS0", "RS1", "F0", "AC", "CY",
/* D8 */
	"0D8h", "0D9h", "0DAh", "0DBh", "0DCh", "0DDh", "0DEh", "0DFh",
/* E0 */
	"ACC.0", "ACC.1", "ACC.2", "ACC.3", "ACC.4", "ACC.5", "ACC.6", "ACC.7",
/* E8 */
	"0E8h", "0E9h", "0EAh", "0EBh", "0ECh", "0EDh", "0EEh", "0EFh",
/* F0 */
	"B.0", "B.1", "B.2", "B.3", "B.4", "B.5", "B.6", "B.7",
/* F8 */
	"0F8h", "0F9h", "0FAh", "0FBh", "0FCh", "0FDh", "0FEh", "0FFh"
};


const  char * pkszSFRname[128] =
{
/* 80 */
	"P0", "SP", "DPL", "DPH", "84h", "85h", "86h", "PCON",
/* 88 */
	"TCON", "TMOD", "TL0", "TL1", "TH0", "TH1", "8Eh", "8Fh",
/* 90 */
	"P1", "91h", "92h", "93h", "94h", "95h", "96h", "97h",
/* 98 */
	"SCON", "SBUF", "9Ah", "9Bh", "9Ch", "9Dh", "9Eh", "9Fh",
/* A0 */
	"P2", "0A1h", "0A2h", "0A3h", "0A4h", "0A5h", "0A6h", "0A7h",
/* A8 */
	"IE", "0A9h", "0AAh", "0ABh", "0ACh", "0ADh", "0AEh", "0AFh",
/* B0 */
	"P3", "0B1h", "0B2h", "0B3h", "0B4h", "0B5h", "0B6h", "0B7h",
/* B8 */
	"IP", "0B9h", "0BAh", "0BBh", "0BCh", "0BDh", "0BEh", "0BFh",
/* C0 */
	"0C0h", "0C1h", "0C2h", "0C3h", "0C4h", "0C5h", "0C6h", "0C7h",
/* C8 */
	"0C8h", "0C9h", "0CAh", "0CBh", "0CCh", "0CDh", "0CEh", "0CFh",
/* D0 */
	"PSW", "0D1h", "0D2h", "0D3h", "0D4h", "0D5h", "0D6h", "0D7h",
/* D8 */
	"0D8h", "0D9h", "0DAh", "0DBh", "0DCh", "0DDh", "0DEh", "0DFh",
/* E0 */
	"ACC", "0E1h", "0E2h", "0E3h", "0E4h", "0E5h", "0E6h", "0E7h",
/* E8 */
	"0E8h", "0E9h", "0EAh", "0EBh", "0ECh", "0EDh", "0EEh", "0EFh",
/* F0 */
	"B", "0F1h", "0F2h", "0F3h", "0F4h", "0F5h", "0F6h", "0F7h",
/* F8 */
	"0F8h", "0F9h", "0FAh", "0FBh", "0FCh", "0FDh", "0FEh", "0FFh"
};



/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*
*  Command function 'DA':  Disassemble program code at specified address.
*
*  The disassembler is invoked by the command line "DA aaaa [x]"
*      where 'aaaa' is the starting address of the code to be disassembled and
*      'x' is an optional parameter (any char) to request continuous output.
*
*  If 'x' is omitted, 20 lines (max) are output at a time, followed by a pause,
*  thereupon which the user can press Escape to quit or any other key to continue.
*  If 'x' is present, disassembly stops if an undefined opcode ($A5) is found,
*  or if the user hits any key.
*
*  Arg1 @ CmdLine[3] is code addr (0000..FFFF)
*  Arg2 @ CmdLine[8] is switch to disable pause (optional)
*/
void
disassemble_cmd( void )
{
	const   char  * pkszNextBlurb;                // Pointer to next part of line to be output
	uint16  uwFetchAddr;                          // Address of next code byte to fetch
	uint8   bLinesOutput = 0;                     // Lines output on current "page" (20 lines)
	bool    yOptNoPause = FALSE;                  // TRUE if "no pause" option is selected
	bool    yContinue = TRUE;
	int8    ibRelAddr;
	uint8   bOpcode;
	uint8   bOperand;
	uint16  uwOperand;
	uint8   bAddrMode;

	uwFetchAddr = hexatoi( &gacCmdLine[3] );      // Start addr
	if ( isprint( gacCmdLine[8] ) )  yOptNoPause = TRUE;

	while ( yContinue )
	{
		putch( '\t' );
		putHexword( uwFetchAddr );
		putch( '\t' );
		bOpcode = peek_code_byte( uwFetchAddr++ );
		pkszNextBlurb = put_assembler( pkszMnemonic[bOpcode] );
		bAddrMode = kabOperandType[bOpcode];

		switch ( bAddrMode )
		{
		case 0:  // Illegal opcode
			yContinue = FALSE;
			break;

		case 1:  // No operands
			break;

		case 2:  // one immediate operand
			putch( '$' );  putHexbyte( peek_code_byte( uwFetchAddr++ ) );
			break;

		case 3:  //  one direct operand (use SFR name if oprnd addr >= $80)
			bOperand = peek_code_byte( uwFetchAddr++ );
			if ( bOperand >= 0x80 )  putconstr( pkszSFRname[bOperand - 0x80] );
			else  { putch( '$' );  putHexbyte( bOperand ); }
			put_assembler( pkszNextBlurb );
			break;

		case 4:  // one bit-addressed operand (use SFR bit name if oprnd addr >= $80)
			bOperand = peek_code_byte( uwFetchAddr++ );
			if ( bOperand >= 0x80 )  putconstr( pkszSFRbitname[bOperand - 0x80] );
			else  { putch( '$' );  putHexbyte( bOperand ); }
			put_assembler( pkszNextBlurb );
			break;

		case 5:  // one relative address operand (8 bits, signed)
			ibRelAddr = peek_code_byte( uwFetchAddr++ );
			uwOperand = (uint16) ((int16)uwFetchAddr + (int16)ibRelAddr);
			putch( '$' );  putHexword( uwOperand );
			break;

		case 6:  // one absolute address operand (11 bits)
			uwOperand  = ((uint16)(bOpcode & 0xE0)) << 3;       // bits 10,9,8 (from opcode)
			uwOperand |= peek_code_byte( uwFetchAddr++ );       // bits 7..0   (from operand byte)
			uwOperand |= (uwFetchAddr & 0xF800);                // bits 15..11 (from PCH)
			putch( '$' );  putHexword( uwOperand );
			break;

		case 7:   // two-byte immediate operand (MSB first)
		case 13:  // two-byte long address operand
			uwOperand  = (uint16)peek_code_byte( uwFetchAddr++ ) << 8;   // MSB
			uwOperand |= peek_code_byte( uwFetchAddr++ );                // LSB
			putch( '$' );  putHexword( uwOperand );
			break;

		case 8:  // two 1-byte operands: direct, immediate
			bOperand = peek_code_byte( uwFetchAddr++ );    // operand 1
			if ( bOperand >= 0x80 )  putconstr( pkszSFRname[bOperand - 0x80] );
			else  { putch( '$' );  putHexbyte( bOperand ); }
			put_assembler( pkszNextBlurb );
			bOperand = peek_code_byte( uwFetchAddr++ );    // operand 2
			putch( '$' );  putHexbyte( bOperand );
			break;

		case 9:  // two 1-byte operands: direct, direct
			bOperand = peek_code_byte( uwFetchAddr++ );    // operand 1
			if ( bOperand >= 0x80 )  putconstr( pkszSFRname[bOperand - 0x80] );
			else  { putch( '$' );  putHexbyte( bOperand ); }
			put_assembler( pkszNextBlurb );
			bOperand = peek_code_byte( uwFetchAddr++ );    // operand 2
			if ( bOperand >= 0x80 )  putconstr( pkszSFRname[bOperand - 0x80] );
			else  { putch( '$' );  putHexbyte( bOperand ); }
			break;

		case 10:  // two operands: immediate, relative address
			bOperand = peek_code_byte( uwFetchAddr++ );    // operand 1
			putch( '$' );  putHexbyte( bOperand );
			put_assembler( pkszNextBlurb );
			ibRelAddr = peek_code_byte( uwFetchAddr++ );   // operand 2
			uwOperand = (uint16) ((int16)uwFetchAddr + (int16)ibRelAddr);
			putch( '$' );  putHexword( uwOperand );
			break;

		case 11:  // two operands: direct, relative address
			bOperand = peek_code_byte( uwFetchAddr++ );    // operand 1
			if ( bOperand >= 0x80 )  putconstr( pkszSFRname[bOperand - 0x80] );
			else  { putch( '$' );  putHexbyte( bOperand ); }
			put_assembler( pkszNextBlurb );
			ibRelAddr = peek_code_byte( uwFetchAddr++ );   // operand 2
			uwOperand = (uint16) ((int16)uwFetchAddr + (int16)ibRelAddr);
			putch( '$' );  putHexword( uwOperand );
			break;

		case 12:  // two operands: bit address, relative address
			bOperand = peek_code_byte( uwFetchAddr++ );    // operand 1
			if ( bOperand >= 0x80 )  putconstr( pkszSFRbitname[bOperand - 0x80] );
			else  { putch( '$' );  putHexbyte( bOperand ); }
			put_assembler( pkszNextBlurb );
			ibRelAddr = peek_code_byte( uwFetchAddr++ );   // operand 2
			uwOperand = (uint16) ((int16)uwFetchAddr + (int16)ibRelAddr);
			putch( '$' );  putHexword( uwOperand );
			break;

		default:  // corrupted look-up table?
			yContinue = FALSE;
			break;
		}  // end switch

		putNewLine();
		bLinesOutput++ ;
		if ( yOptNoPause && hci_data_avail() )  { getch();  break; }    // quit
		if ( !yOptNoPause && bLinesOutput >= 20 )                       // pause
		{
			if ( getch() == ESC )  break;
			bLinesOutput = 0;
		}
	}
}


/*
*   Function:  put_assembler
*
*   The function outputs characters at pkcSourcePtr until either a place marker "%s" is
*   found or a NUL is found (end of string). The place marker "%s" is not output, but the
*   pointer is advanced so that it points to the next char after "%s" before returning.
*   If a NUL is found, the pointer remains at the NUL.
*
*   Entry Arg:  (char *) pkcSourcePtr = pointer to somewhere in a string from pkszMnemonic;
*   Returns:    (char *) pkcSourcePtr = pointer advanced to char after place marker (%s);
*/
const char *
put_assembler( const char * pkcSourcePtr )
{
	char  c;

	while ( (c = *pkcSourcePtr) != NUL )
	{
		if ( c == '%' )  { pkcSourcePtr += 2;  break; }
		putch( c );
		pkcSourcePtr++ ;
	}
	return  pkcSourcePtr;
}


#endif  // DISASM_INCLUDED

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -