📄 opset.c
字号:
#ifndef lintstatic char sccsid[] = "@(#)opset.c 4.4 5/12/83";#endif lint/* * UNIX debugger * Instruction printing routines. * MACHINE DEPENDENT */#ifdef ADB#include "defs.h"#endif ADB#ifdef SDB#include "head.h"#endif SDBL_INT dot;INT dotinc;L_INT insoutvar[36];#ifdef ADBL_INT var[36];#endif ADB#undef INSTTAB#include "instrs.h"STRING regname[];STRING fltimm[];POS type, space, incp;/* * Definitions for registers and for operand classes */char *insregname(); /* how to print a register */#define R_PC 0xF#define OC_IMM0 0x0#define OC_IMM1 0x1#define OC_IMM2 0x2#define OC_IMM3 0x3#define OC_INDEX 0x4#define OC_REG 0x5#define OC_DREG 0x6#define OC_ADREG 0x7#define OC_AIREG 0x8#define OC_DAIREG 0x9#define OC_BDISP 0xA#define OC_DBDISP 0xB#define OC_WDISP 0xC#define OC_DWDISP 0xD#define OC_LDISP 0xE#define OC_DLDISP 0xF#define OC_SHIFT 4#define OC_CONS(oc,reg) (((oc & 0xF) << OC_SHIFT) | (reg & 0xF))#define OC_AMEXT(x) (((x) >> OC_SHIFT) & 0xF)#define OC_REGEXT(x) ((x) & 0xF)/* * Definitions for large numbers */#include "asnumber.h"typedef struct as_number *numberp;numberp snarf();numberp snarfreloc();/* * Definitions for special instructions */#define CASEB 0x8F#define CASEW 0xAF#define CASEL 0xCF/* * Definitions for converting TYP's into numbers, booleans, etc. * These are shared with the assembler. */extern int ty_NORELOC[];extern int ty_float[];extern int ty_nbyte[];extern int ty_nlg[];extern char *ty_string[];short ioptab[3][256]; /* two level 1-based index by opcode into insttab */int mapescbyte(byte) u_char byte;{ switch(byte){ default: return(0); case ESCD: return(1); case ESCF: return(2); }}mkioptab(){ REG struct insttab *p; int mapchar; for(p = insttab; p->iname; p++){ mapchar = mapescbyte(p->eopcode); if (ioptab[mapchar][p->popcode]) continue; ioptab[mapchar][p->popcode] = (p - insttab) + 1; }}u_char snarfuchar();/* * Global variables for communicating with the minions and printins */static int idsp;static short argno; /* which argument one is working on */static char insoutfmt[2]; /* how to format the relocated symbols */#ifdef SDBstatic struct proct *procp;#endif SDBstatic savevar(val) long val;{ var[argno] = val; insoutvar[argno] = val;}printins(fmt, Idsp, ins) char fmt;#ifndef vax u_char ins;#else u_char ins;#endif int Idsp;{ u_char mode; /* mode */ u_char ins2; char *indexreg; /* print of which register indexes */ char *indexed; /* we indexed */ char *operandout(); REG u_char *ap; REG struct insttab *ip; u_char optype; int mapchar; idsp = Idsp; type = DSYM; space = idsp;#ifdef SDB procp = adrtoprocp(dot); if (procp->paddr == dot){ printf("0x%04.4x", ins); incp = 2; goto ret; }#endif SDB#ifdef ADB insoutfmt[0] = 0;#endif ADB#ifdef SDB insoutfmt[0] = fmt;#endif SDB incp = 1; if ((mapchar = mapescbyte(ins)) != 0){ ins2 = snarfuchar(); if (ioptab[mapchar][ins2] == 0){ /* * Oops; not a defined instruction; * back over this escape byte. */ incp -= 1; mapchar = 0; } else { ins = ins2; } } if (ioptab[mapchar][ins] == 0){ printf("<undefined operator byte>: %x", ins); goto ret; } ip = &insttab[ioptab[mapchar][ins] - 1]; printf("%s\t", ip->iname); for (ap = ip->argtype, argno = 0; argno < ip->nargs; argno++, ap++) { savevar(0x80000000); /* an illegal symbol */ optype = *ap; if (argno != 0) printc(','); indexreg = 0; indexed = 0; do{ if (A_ACCEXT(optype) & ACCB){ switch(A_TYPEXT(optype)){ case TYPB: mode = OC_CONS(OC_BDISP, R_PC); break; case TYPW: mode = OC_CONS(OC_WDISP, R_PC); break; } } else { mode = snarfuchar(); } indexreg = operandout(mode, optype); if (indexed) printf("[%s]", indexed); indexed = indexreg; } while(indexed); } if (mapchar == 0){ switch(ins){ case CASEB: case CASEW: case CASEL: casebody(insoutvar[1], insoutvar[2]); break; default: break; } } ret: ;#ifdef SDB oincr = incp;#endif SDB#ifdef ADB dotinc = incp;#endif ADB}casebody(base, limit) long base; long limit;{ int i; POS baseincp; POS advincp; struct as_number *valuep;#define OSIZE (sizeof(short)) argno = 0; baseincp = incp; for (i = 0; i <= limit; i++) { printc(EOR);#ifdef SDB printf(" %d: ", i + base);#endif SDB#ifdef ADB printf(" %R: ", i + base);#endif ADB valuep = snarfreloc(OSIZE, 0); advincp = incp; incp = baseincp; dispaddress(valuep, OC_CONS(OC_WDISP, R_PC)); incp = advincp; }}/* * magic values to mung an offset to a register into * something that psymoff can understand.. all magic */ /* 0 1 2 3 4 */static long magic_masks[5] = {0, 0x80, 0x8000, 0, 0}; static long magic_compl[5] = {0, 0x100, 0x10000,0, 0};/* * Snarf up some bytes, and put in the magic relocation flags */numberp snarfreloc(nbytes) int nbytes;{ numberp back; back = snarf(nbytes); if (back->num_ulong[0] & magic_masks[nbytes]) back->num_ulong[0] -= magic_compl[nbytes]; return(back);}/* * The following code is NOT portable from the PDP 11 to the VAX * because of the byte ordering problem. */numberp snarf(nbytes) int nbytes;{ REG int i; static struct as_number backnumber; static struct as_number znumber; /* init'ed to 0 */ backnumber = znumber; for (i = 0; i < nbytes; i++) backnumber.num_uchar[i] = snarfuchar(); return(&backnumber);}/* * Read one single character, and advance the dot */u_char snarfuchar(){ u_char back; /* * assert: bchkget and inkdot don't have side effects */ back = (u_char)bchkget(inkdot(incp), idsp); incp += 1; return(back);}/* * normal operand; return non zero pointer to register * name if this is an index instruction. */char *operandout(mode, optype) u_char mode; u_char optype;{ char *r; int regnumber; int nbytes; regnumber = OC_REGEXT(mode); r = insregname(regnumber); switch (OC_AMEXT(mode)){ case OC_IMM0: case OC_IMM1: case OC_IMM2: case OC_IMM3: shortliteral(mode, optype); return(0); case OC_INDEX: return(r); /* will be printed later */ case OC_REG: printf("%s", r); return(0); case OC_DREG: printf("(%s)", r); return(0); case OC_ADREG: printf("-(%s)", r); return(0); case OC_DAIREG: printc('*'); case OC_AIREG: if (regnumber == R_PC){ pcimmediate(mode, optype); } else { printf("(%s)+", r); } return(0); case OC_DBDISP: printc('*'); case OC_BDISP: nbytes = 1; break; case OC_DWDISP: printc('*'); case OC_WDISP: nbytes = 2; break; case OC_DLDISP: printc('*'); case OC_LDISP: nbytes = 4; break; } dispaddress(snarfreloc(nbytes), mode); return(0);}dispaddress(valuep, mode) numberp valuep; u_char mode;{ int regnumber = OC_REGEXT(mode); switch(OC_AMEXT(mode)){ case OC_BDISP: case OC_DBDISP: case OC_WDISP: case OC_DWDISP: case OC_LDISP: case OC_DLDISP: if (regnumber == R_PC){ /* PC offset addressing */ valuep->num_ulong[0] += inkdot(incp); } }#ifdef ADB psymoff(valuep->num_ulong[0], type, &insoutfmt[0]); if (regnumber != R_PC){ /* } */#endif ADB#ifdef SDB if(psymoff(valuep->num_ulong[0], regnumber, &insoutfmt[0]) && (regnumber != R_PC)){#endif SDB printf("(%s)", insregname(regnumber)); } savevar((long)valuep->num_ulong[0]);}/* * get a register name */char *insregname(regnumber) int regnumber;{ char *r; r = regname[regnumber];#ifdef SDB if ( (insoutfmt[0] == 'i') && (regnumber >= 6) && (regnumber <= 11) && (adrtoregvar(regnumber, procp) != -1)) { r = sl_name; }#endif SDB return(r);}/* * print out a short literal */shortliteral(mode, optype) u_char mode; u_char optype;{ savevar((long)mode); switch(A_TYPEXT(optype)){ case TYPF: case TYPD: case TYPG: case TYPH: printf("$%s", fltimm[mode]); break; default:#ifdef ADB printf("$%r", mode);#endif ADB#ifdef SDB printf("$%d", mode);#endif SDB break; }}pcimmediate(mode, optype) u_char mode; u_char optype;{ int nbytes; printc('$'); if (mode == OC_CONS(OC_DAIREG, R_PC)){ /* PC absolute, always 4 bytes*/ dispaddress(snarfreloc(4), mode); return; } nbytes = ty_nbyte[A_TYPEXT(optype)]; if (! ty_NORELOC[A_TYPEXT(optype)]){ dispaddress(snarfreloc(nbytes), mode); return; } bignumprint(nbytes, optype);}bignumprint(nbytes, optype) int nbytes; u_char optype;{ numberp valuep; int leading_zero = 1; REG int bindex; REG int nindex; REG int ch; valuep = snarf(nbytes); switch(A_TYPEXT(optype)){ case TYPF: printf("0f%f", valuep->num_num.numFf_float.Ff_value); break; case TYPD: printf("0d%f", valuep->num_num.numFd_float.Fd_value); break; case TYPG: printf("0g::"); goto qprint; case TYPH: printf("0h::"); goto qprint; case TYPQ: case TYPO: qprint: for (bindex = nbytes - 1; bindex >= 0; --bindex){ for (nindex = 4; nindex >= 0; nindex -= 4){ ch = (valuep->num_uchar[bindex] >> nindex); ch &= 0x0F; if ( ! (leading_zero &= (ch == 0) ) ){ if (ch <= 0x09) printc(ch + '0'); else printc(ch - 0x0A + 'a'); } } } break; }}#ifdef SDBL_INT inkdot(incr) int incr;{ L_INT newdot; newdot = dot + incr; return(newdot);}printc(c) char c;{ printf("%c", c);}psymoff(v, regnumber, fmt) L_INT v; char *fmt;{ struct proct *procp; REG int diff; if (fmt[0] == 'i') { switch(regnumber){ case 12: /* parameter */ if ((diff = adrtoparam((ADDR) v, adrtoprocp(dot))) != -1) { printf("%s", sl_name); prdiff(diff); return(0); } break; case 13: /* local */ if ((diff = adrtolocal((ADDR) -v, adrtoprocp(dot)) ) != -1) { printf("%s", sl_name); prdiff(diff); return(0); } break; default: break; } if (v < firstdata) { if ((procp = adrtoprocp((ADDR) v)) != badproc) { prlnoff(procp, v); return(0); } } else { if ((diff = adrtoext((ADDR) v)) != -1) { printf("%s", sl_name); prdiff(diff); return(0); } } } prhex(v); return(1);}prdiff(diff){ if (diff) { printf("+"); prhex(diff); }}#endif SDB
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -