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

📄 disassembler.c

📁 at51系列单片机编程源码
💻 C
📖 第 1 页 / 共 2 页
字号:
}/* This Function calculates the target address from an indirect addressing * command using an 8 bit address relative to the program counter. * The return value is an absolute 16 bit address. */intdecodeRelAddr(struct MemoryMap *MemMap, int pass,                 unsigned char operand, int memPtr){	int addr;	/* calculate address */	addr = memPtr + (signed char)operand;	/* if in pass 1 check if this address has already been labelled */	if (pass == 1)		addLabel(MemMap, addr, CODE);	return addr;}voidprintHexList (struct MemoryMap *MemMap, struct MemChunk *Chunk,                 int addr, int len){	printf("  %04Xh   %02X", addr-len, getByte(addr-len));	switch(len) {	case 3:		printf(" %02X", getByte(addr-2));	case 2:		printf(" %02X", getByte(addr-1));		if(len == 2)			printf("   ");		break;	default:		printf("      ");	}	printf("   ");}/* dis_inst: Disassemble one instruction (pass 1) * Also increments memPtr to point to the next instruction address. * * Return -1 on error. Otherwise, return opcode byte. * * CAVEAT: Indirect jumps not handled completely (JMP @A+DPTR) */static intdis_inst1(struct MemoryMap *MemMap, struct MemChunk *Chunk, int memPtr){	unsigned char opcode, op1, op2;	int newaddr = -1;	MemMap->flags[memPtr] |= ADR_OPCODE;  /* mark the beginning of a command */	opcode = getNextByte(1);	switch(op_format[opcode]) {		case 0:      /* A5 is an illegal opcode */			fprintf(stderr,			   "Illegal opcode A5 at address %04X\n", memPtr-1);			newaddr = -1;			break;		case 1:     /* no operands */			newaddr = memPtr;			if ((opcode & 0xef) == 0x22)     /* RET or RETI ?*/				newaddr = -1;                /* ->stop disassembling */			else if (opcode == 0x73) {       /* JMP @A+DPTR ?*/				addCodeEntryRange(MemMap, DPTR, 256);				newaddr = -1;			} else if (opcode == 0x83)       /* MOVC A,@A+PC */				addLabel(MemMap, memPtr, DATA);			else if (opcode == 0x93)         /* MOVC A,@A+DPTR */				addLabel(MemMap, DPTR, DATA);			else if (opcode == 0xa3)         /* INC DPTR ? */				DPTR++;                      /* ->track DPTR */			break;		case 2:		case 3:		case 4:     /* one operand */			getNextByte(1);			newaddr = memPtr;			break;		case 5:     /* one operand, relative address */			op1 = getNextByte(1);			/* relative addr calculation */			newaddr = decodeRelAddr(MemMap, 1, op1, memPtr);			/* if this is a branch, continue disassembly */			if (opcode != 0x80)				pass1(MemMap, Chunk, memPtr);			break;		case 6:     /* one operand, absolute address */			op1 = getNextByte(1);			/* absolute addr calculation */			newaddr = decodeAbsAddr(MemMap, 1, opcode, op1, memPtr);			/* if this is a call, continue disassembly */			if (opcode & 0x10)				pass1(MemMap, Chunk, memPtr);			break;		case 7:		case 8:		case 9:     /* two operands */			op1 = getNextByte(1);			op2 = getNextByte(1);			newaddr = memPtr;			if (opcode == 0x90)   /* MOV DPTR, #16 ? */				DPTR = ((((int)op1)<<8) | op2);  /* ->track DPTR */			break;		case 10:		case 11:		case 12:    /* two operands, relative address */			getNextByte(1);			op2 = getNextByte(1);			/* relative addr calculation */			newaddr = decodeRelAddr(MemMap, 1, op2, memPtr);			/* this is always a branch instruction */			pass1(MemMap, Chunk, memPtr);			break;		case 13:     /* long address */			op1 = getNextByte(1);			op2 = getNextByte(1);			/* long addr calculation */			newaddr = decodeLongAddr(MemMap, 1, op1, op2);			/* if this is a call, continue disassembly */			if (opcode == 0x12)				pass1(MemMap, Chunk, memPtr);			break;		default:     /* error in op_format table */			fprintf(stderr,			     "Invalid opcode format, error in format table\n");			newaddr = -1;			break;	}	return newaddr;}/* dis_inst2: Disassemble one instruction to ofile * * Returns address immediately after instruction. */intdis_inst2(struct MemoryMap *MemMap, struct MemChunk *Chunk, int memPtr){	unsigned char opcode, op1 = 0, op2 = 0;	char buffer[6];	int bytes = 1, addr;	/* Fetch opcode */	opcode = getNextByte(2);	/* Fetch second and third byte, if appropriate */	if (op_format[opcode] > 1) {		op1 = getNextByte(2);		bytes = 2;	}	if (op_format[opcode] > 6) {		op2 = getNextByte(2);		bytes = 3;	}	/* Output decoded instruction */	printHexList(MemMap, Chunk, memPtr, bytes);	switch(op_format[opcode]) {		case 0:      /* A5 is an illegal opcode */			printf("DB 85h  ; illegal opcode");		case 1:      /* no operands */			printf(mnemonic[opcode]);			break;		case 2:      /* one immediate operand */			printf(mnemonic[opcode], formatHexValue(op1));			break;		case 3:      /* one direct operand */			printf(mnemonic[opcode], decodeSFR(op1));			break;		case 4:      /* one bit-addressed operand */			printf(mnemonic[opcode], decodeSFBit(op1));			break;		case 5:      /* one operand, relative address */			addr = decodeRelAddr(MemMap, 2, op1, memPtr);			printf(mnemonic[opcode], getLabelName(MemMap, addr, CODE));			break;		case 6:      /* one operand, absolute address */			addr = decodeAbsAddr(MemMap, 2, opcode, op1, memPtr);			printf(mnemonic[opcode], getLabelName(MemMap, addr, CODE));			break;		case 7:      /* two-byte immediate operand */			/* MOV DPTR, #immediate16 */			addr = decodeLongAddr(MemMap, 2, op1, op2);			printf(mnemonic[opcode], getLabelName(MemMap, addr, DATA));			break;		case 8:      /* two operands: direct, immediate */			strcpy(buffer, decodeSFR(op1));			printf(mnemonic[opcode], buffer, formatHexValue(op2));			break;		case 9:      /* two operands: direct, direct */			/* (operands in reverse order) */			strcpy(buffer, decodeSFR(op1));			printf(mnemonic[opcode], decodeSFR(op2), buffer);			break;		case 10:     /* two operands: immediate, relative */			addr = decodeRelAddr(MemMap, 2, op2, memPtr);			printf(mnemonic[opcode], formatHexValue(op1), getLabelName(MemMap, addr, CODE));			break;		case 11:     /* two operands: direct, relative */			addr = decodeRelAddr(MemMap, 2, op2, memPtr);			printf(mnemonic[opcode], decodeSFR(op1), getLabelName(MemMap, addr, CODE));			break;		case 12:     /* two operands: bit, relative */			addr = decodeRelAddr(MemMap, 2, op2, memPtr);			printf(mnemonic[opcode], decodeSFBit(op1), getLabelName(MemMap, addr, CODE));			break;		case 13:     /* long address */			addr = decodeLongAddr(MemMap, 2, op1, op2);			printf(mnemonic[opcode], getLabelName(MemMap, addr, CODE));			break;		default:     /* error in op_format table */			printf("DB %02Xh  ; error in op_format table", opcode);	}	printf("\n");	return memPtr;}/* This is a helper function for dissassembler pass1. It disassembles * one thread of instructions starting at given entry point. This * function will be called recursively. */voidpass1(struct MemoryMap *MemMap, struct MemChunk *Chunk, int addr){	while ((addr != -1) && ((MemMap->flags[addr] & ADR_USED) == 0))		/* no error, we haven't been here before, and non-empty */		/* disassemble next instruction */		addr = dis_inst1(MemMap, Chunk, addr);}/* pass1 of the disassember. Disassemble instructions starting with * the first marked code entry point found. */voiddisassembler_pass1(struct MemoryMap *MemMap, struct MemChunk *Chunk){	int addr;	do {		for (addr=0; addr < MemMap->mapsize; addr++)			if ((MemMap->flags[addr] & ADR_ENTRY) && /* Entry point */			!(MemMap->flags[addr] & ADR_CODE)) { /* and not yet code ? */				pass1(MemMap, Chunk, addr);       /* then track code */				MemMap->flags[addr] |= ADR_ENTRY; /* and mark real entry point */				break;			}	} while (addr < MemMap->mapsize);}/* pass2 of the disassember. Try to find out which addresses are unused * and save the results in the MemoryMap. */voiddisassembler_pass2(struct MemoryMap *MemMap, struct MemChunk *Chunk){	int n, cnt, ch, mode, addr;	cnt = ch = mode = 0;            /* for gcc stop complaining */	while (Chunk->header.length) {		for (n=0; n < Chunk->header.length; n++) {			addr = Chunk->header.address + n;    /* substitution */			if (n == 0) ch = Chunk->data[0] + 1; /* ensure that ch != Chunk->data[0] */			if (Chunk->data[n] != ch) {				ch = Chunk->data[n];     /* reset variables */				cnt = 0; mode = 0;			}			if (MemMap->flags[addr] == 0 && Chunk->data[n] == ch) {				/* if the address is unused and filled with the same   *				 * character as the address before count it and switch *				 * mode if a chain of more than 4 identical characters *				 * have been found. Mark the found chain and following *				 * characters of the same kind as free.                */				if (mode == 0) {					/* chain not found yet */					if (++cnt > 3 && (ch == 0x00 || ch == 0xFF)) {						for (cnt--; cnt >= 0; cnt--)							MemMap->flags[addr - cnt] |= ADR_FREE;						mode = 1;					}				} else /* continue chain */					MemMap->flags[addr] |= ADR_FREE;			}		}		Chunk = (struct MemChunk*) ((char*) Chunk + sizeof(struct MemChunkHeader) + Chunk->header.length);	}}/* pass3 of the disassembler. Disassemble memory and print the results * to stdout. */voiddisassembler_pass3(struct MemoryMap *MemMap, struct MemChunk *Chunk){	int addr = 0;	unsigned char empty = 1; /* 1 for no code/data, 0 for code or data */	while (addr < MemMap->mapsize)	{		/* Step 1: check if memory is empty */		if (!(MemMap->flags[addr] & ADR_FREE) && (empty))			/* We've changed from empty to non-empty,			 * so start a new segment.			 */			printf("CSEG AT %04Xh\n", addr);		else if (MemMap->flags[addr] & ADR_FREE) {			/* no code or data here */			++addr;			empty = 1;			continue;		}		empty = 0;		/* Step 2: Output a label if one exists */		if (MemMap->flags[addr] & ADR_CLABEL)			printf("%s: ", getLabelName(MemMap, addr, CODE));		else if (MemMap->flags[addr] & ADR_DLABEL)			printf("%s: ", getLabelName(MemMap, addr, DATA));		else if (MemMap->flags[addr] & ADR_ENTRY)			printf("E -->  ");		else			printf("       ");		/* Step 3: Output code or data as appropriate */		if (MemMap->flags[addr] & ADR_CODE)			/* code here, so disassemble next instruction */			addr = dis_inst2(MemMap, Chunk, addr);		else {			/* data here */			printHexList(MemMap, Chunk, addr+1, 1);			if(isprint(getByte(addr)))				printf("DB %02Xh ; '%c'\n", getByte(addr), getByte(addr));			else				printf("DB %02Xh \n", getByte(addr));			++addr;		}	}	printf("END\n");}

⌨️ 快捷键说明

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