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

📄 disassembler.c

📁 <B>Digital的Unix操作系统VAX 4.2源码</B>
💻 C
📖 第 1 页 / 共 2 页
字号:
/* --------------------------------------------------------- *//* | Copyright (c) 1986, 1989 MIPS Computer Systems, Inc.  | *//* | All Rights Reserved.                                  | *//* --------------------------------------------------------- *//* $Header: disassembler.c,v 2010.2.1.3 89/11/29 14:29:53 bettina Exp $ *//* * Copyright 1985 by, 1989 MIPS Computer Systems, Inc. *//* MIPS instruction disassembler, callable from either Pascal or C */#include <stdio.h>#include "syntax.h"#ifndef SYSV#	include <machine/inst.h>#else#	include <sys/inst.h>#endif#ifndef ftrunc_op#define ftrunc_op	0x0c#define fround_op	0x0d#define ffloor_op	0x0e#define fceil_op	0x0f#endif#include <opnames.h>#include <disassembler.h>/* register definitions */#define ZERO 0private char *c1fmt_name[16] = {	"s",	"d",	"e",	"q",	"w",	"fmt5",	"fmt6",	"fmt7",	"fmt8",	"fmt9",	"fmta",	"fmtb",	"fmtc",	"fmtd",	"fmte",	"fmtf"};/* public *//* Three sets of commonly used register names *//* const */ char *dis_reg_names[3][32] = {	{	/* compiler names */		"zero",	"at",	"v0",	"v1",	"a0",	"a1",	"a2",	"a3",		"t0",	"t1",	"t2",	"t3",	"t4",	"t5",	"t6",	"t7",		"s0",	"s1",	"s2",	"s3",	"s4",	"s5",	"s6",	"s7",		"t8",	"t9",	"k0",	"k1",	"gp",	"sp",	"s8",	"ra"	},	{	/* hardware names */		"r0",	"r1",	"r2",	"r3",	"r4",	"r5",	"r6",	"r7",		"r8",	"r9",	"r10",	"r11",	"r12",	"r13",	"r14",	"r15",		"r16",	"r17",	"r18",	"r19",	"r20",	"r21",	"r22",	"r23",		"r24",	"r25",	"r26",	"r27",	"gp",	"sp",	"r30",	"r31"	},	{	/* assembler names */		"$0",	"$at",	"$2",	"$3",	"$4",	"$5",	"$6",	"$7",		"$8",	"$9",	"$10",	"$11",	"$12",	"$13",	"$14",	"$15",		"$16",	"$17",	"$18",	"$19",	"$20",	"$21",	"$22",	"$23",		"$24",	"$25",	"$26",	"$27",	"$gp",	"$sp",	"$30",	"$31"	}};/* Remember the options set by dis_init */#define ADDR_DEFAULT "%#010x\t"#define VALUE_DEFAULT "%#010x\t"#define NAME_DEFAULT COMPILER_NAMESprivate struct {  char *addr_format;  char *value_format;  char **reg_names;  int print_jal_targets;  } save = {    ADDR_DEFAULT,    VALUE_DEFAULT,    NAME_DEFAULT,    true    };/* public -- see .h file */voiddis_init(addr_format, value_format, reg_names, print_jal_targets)  char *addr_format;  char *value_format;  char *reg_names[];  int print_jal_targets;  {  if (addr_format) save.addr_format = addr_format;  else save.addr_format = ADDR_DEFAULT;  if (value_format) save.value_format = value_format;  else save.value_format = VALUE_DEFAULT;  if (reg_names) save.reg_names = reg_names;  else save.reg_names = NAME_DEFAULT;  save.print_jal_targets = print_jal_targets;  }/* Update regmask to reflect the use of this general-purpose (not fp)  register, and return its name */private char *register_name(ireg, regmask)  unsigned ireg, *regmask;  {  *regmask |= (1 << ireg);  return save.reg_names[ireg];  }private char *fp_register_name(r)  unsigned r;{  static char *name[32] = {    "$f0",  "$f1",  "$f2",  "$f3",  "$f4",  "$f5",  "$f6",  "$f7",    "$f8",  "$f9",  "$f10", "$f11", "$f12", "$f13", "$f14", "$f15",    "$f16", "$f17", "$f18", "$f19", "$f20", "$f21", "$f22", "$f23",    "$f24", "$f25", "$f26", "$f27", "$f28", "$f29", "$f30", "$f31" };  return name[r];}private char *c0_register_name(r)  unsigned r;{  return c0reg_name[r];}/* public -- see .h file */intdisasm(buffer, address, iword, regmask, symbol_value, ls_register)  char *buffer;  unsigned address, iword, *regmask, *symbol_value, *ls_register;{  int return_value = 0;  char *bufptr = buffer;  boolean do_b_displacement = false;  boolean do_loadstore = false;  union mips_instruction i;  i.word = iword;  *regmask = *symbol_value = *ls_register = 0;  /* Put out the address and hex value of the instruction,     leaving bufptr set at the end */  if (save.addr_format) {    sprintf(bufptr, save.addr_format, address);    bufptr += strlen(bufptr);  }  if (save.value_format) {    sprintf(bufptr, save.value_format, iword);    bufptr += strlen(bufptr);  }  switch (i.j_format.opcode) {  case spec_op:    if (i.word == 0) {      strcat(bufptr, "nop");      bufptr += strlen(bufptr);      break;    }    else if (i.r_format.func == addu_op && i.r_format.rt == ZERO) {      sprintf(bufptr, "move\t%s,%s",	      register_name(i.r_format.rd, regmask),	      register_name(i.r_format.rs, regmask));      bufptr += strlen(bufptr);      break;    }    strcat(bufptr, spec_name[i.r_format.func]);    bufptr += strlen(bufptr);    switch (i.r_format.func) {    case sll_op:    case srl_op:    case sra_op:      sprintf(bufptr, "\t%s,%s,%d",	      register_name(i.r_format.rd, regmask),	      register_name(i.r_format.rt, regmask),	      i.r_format.re);      break;    case sllv_op:    case srlv_op:    case srav_op:      sprintf(bufptr, "\t%s,%s,%s",	      register_name(i.r_format.rd, regmask),	      register_name(i.r_format.rt, regmask),	      register_name(i.r_format.rs, regmask));      break;    case mfhi_op:    case mflo_op:      sprintf(bufptr, "\t%s",	      register_name(i.r_format.rd, regmask));      break;    case jalr_op:      return_value = 2;      sprintf(bufptr, "\t%s,%s",	      register_name(i.r_format.rd, regmask),	      register_name(i.r_format.rs, regmask));      break;    case jr_op:      return_value = 2;      /* fall through */    case mtlo_op:    case mthi_op:      sprintf(bufptr, "\t%s",	      register_name(i.r_format.rs, regmask));      break;    case tge_op:    case tgeu_op:    case tlt_op:    case tltu_op:    case teq_op:    case tne_op:    case mult_op:    case multu_op:    case div_op:    case divu_op:      sprintf(bufptr, "\t%s,%s",	      register_name(i.r_format.rs, regmask),	      register_name(i.r_format.rt, regmask));      break;    case syscall_op:      break;    case break_op:      {	char *format = "\t%d";	unsigned op2 = i.r_format.rd * 32 + i.r_format.re;		if (op2)	  format = "\t%d,%d";	sprintf(bufptr, format, i.r_format.rs*32+i.r_format.rt,		op2);      }      break;    default:      sprintf(bufptr, "\t%s,%s,%s",	      register_name(i.r_format.rd, regmask),	      register_name(i.r_format.rs, regmask),	      register_name(i.r_format.rt, regmask));      break;    }    break;      case bcond_op:    switch (i.i_format.rt) {    case tgei_op:    case tgeiu_op:    case tlti_op:    case tltiu_op:    case teqi_op:    case tnei_op:      sprintf(bufptr, "%s\t%s,%d",	      bcond_name[i.i_format.rt],	      register_name(i.i_format.rs, regmask),	      i.i_format.simmediate);      break;    default:      sprintf(bufptr, "%s\t%s,",	      bcond_name[i.i_format.rt],	      register_name(i.i_format.rs, regmask));      do_b_displacement = true;      break;    }    break;  case blez_op:  case bgtz_op:  case blezl_op:  case bgtzl_op:    sprintf(bufptr, "%s\t%s,", op_name[i.i_format.opcode],	    register_name(i.i_format.rs, regmask));    do_b_displacement = true;    break;  case beq_op:    if (i.i_format.rs == ZERO && i.i_format.rt == ZERO) {      strcat(bufptr, "b\t");      do_b_displacement = true;      break;    }    /* fall through */  case bne_op:  case beql_op:  case bnel_op:    sprintf(bufptr, "%s\t%s,%s,", op_name[i.i_format.opcode],	    register_name(i.i_format.rs, regmask),	    register_name(i.i_format.rt, regmask));    do_b_displacement = true;    break;  case jal_op:  case j_op:    sprintf(bufptr, "%s\t", op_name[i.j_format.opcode]);    *symbol_value =      ((address+4)&~((1<<28)-1)) + (i.j_format.target<<2);    if (save.print_jal_targets) {      bufptr += strlen(bufptr);      sprintf(bufptr, "%#x", *symbol_value);    }    return_value = 1;    break;      case swc1_op:  case sdc1_op:  case lwc1_op:  case ldc1_op:    sprintf(bufptr, "%s\t%s,", op_name[i.i_format.opcode],	    fp_register_name(i.i_format.rt));    do_loadstore = true;    break;  case swc2_op:  case sdc2_op:  case lwc2_op:  case ldc2_op:  case swc3_op:  case sdc3_op:  case lwc3_op:  case ldc3_op:    sprintf(bufptr, "%s\t$%d,", op_name[i.i_format.opcode],	    i.i_format.rt);    do_loadstore = true;    break;      case lb_op:  case lh_op:  case lw_op:  case ld_op:  case lbu_op:  case lhu_op:  case sb_op:

⌨️ 快捷键说明

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