diff options
Diffstat (limited to 'dis88/distabs.c')
-rw-r--r-- | dis88/distabs.c | 708 |
1 files changed, 708 insertions, 0 deletions
diff --git a/dis88/distabs.c b/dis88/distabs.c new file mode 100644 index 0000000..283fe42 --- /dev/null +++ b/dis88/distabs.c @@ -0,0 +1,708 @@ +static char *sccsid = + "@(#) distabs.c, Ver. 2.1 created 00:00:00 87/09/01"; + + /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * * + * Copyright (C) 1987 G. M. Harding, all rights reserved * + * * + * Permission to copy and redistribute is hereby granted, * + * provided full source code, with all copyright notices, * + * accompanies any redistribution. * + * * + * This file contains the lookup tables and other data * + * structures for the Intel 8088 symbolic disassembler. It * + * also contains a few global routines which facilitate * + * access to the tables, for use primarily by the handler * + * functions. * + * * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +#include "dis.h" /* Disassembler declarations */ + +struct exec HDR; /* Used to hold header info */ + +struct nlist symtab[MAXSYM]; /* Array of symbol table info */ + +struct reloc relo[MAXSYM]; /* Array of relocation info */ + +int symptr = -1, /* Index into symtab[] */ + relptr = -1; /* Index into relo[] */ + +char *REGS[] = /* Table of register names */ + { + "al", "cl", "dl", "bl", "ah", "ch", "dh", "bh", + "ax", "cx", "dx", "bx", "sp", "bp", "si", "di", + "es", "cs", "ss", "ds" + }; + +char *REGS0[] = /* Mode 0 register name table */ + { + "bx_si", "bx_di", "bp_si", "bp_di", "si", "di", "", "bx" + }; + +char *REGS1[] = /* Mode 1 register name table */ + { + "bx_si", "bx_di", "bp_si", "bp_di", "si", "di", "bp", "bx" + }; + +int symrank[6][6] = /* Symbol type/rank matrix */ + { + /* UND ABS TXT DAT BSS COM */ + /* UND */ 5, 4, 1, 2, 3, 0, + /* ABS */ 1, 5, 4, 3, 2, 0, + /* TXT */ 4, 1, 5, 3, 2, 0, + /* DAT */ 3, 1, 2, 5, 4, 0, + /* BSS */ 3, 1, 2, 4, 5, 0, + /* COM */ 2, 0, 1, 3, 4, 5 + }; + + /* * * * * * * * * * * * OPCODE DATA * * * * * * * * * * * */ + +char ADD[] = "\tadd", /* Mnemonics by family */ + OR[] = "\tor", + ADC[] = "\tadc", + SBB[] = "\tsbb", + AND[] = "\tand", + SUB[] = "\tsub", + XOR[] = "\txor", + CMP[] = "\tcmp", + NOT[] = "\tnot", + NEG[] = "\tneg", + MUL[] = "\tmul", + DIV[] = "\tdiv", + MOV[] = "\tmov", + ESC[] = "\tesc", + TEST[] = "\ttest", + AMBIG[] = "", + ROL[] = "\trol", + ROR[] = "\tror", + RCL[] = "\trcl", + RCR[] = "\trcr", + SAL[] = "\tsal", + SHR[] = "\tshr", + SHL[] = "\tshl", + SAR[] = "\tsar"; + +char *OPFAM[] = /* Family lookup table */ + { + ADD, OR, ADC, SBB, AND, SUB, XOR, CMP, + NOT, NEG, MUL, DIV, MOV, ESC, TEST, AMBIG, + ROL, ROR, RCL, RCR, SAL, SHR, SHL, SAR + }; + +struct opcode optab[] = /* Table of opcode data */ + { + ADD, aohand, 2, 4, /* 0x00 */ + ADD, aohand, 2, 4, /* 0x01 */ + ADD, aohand, 2, 4, /* 0x02 */ + ADD, aohand, 2, 4, /* 0x03 */ + ADD, aohand, 2, 2, /* 0x04 */ + ADD, aohand, 3, 3, /* 0x05 */ + "\tpush\tes", sbhand, 1, 1, /* 0x06 */ + "\tpop\tes", sbhand, 1, 1, /* 0x07 */ + OR, aohand, 2, 4, /* 0x08 */ + OR, aohand, 2, 4, /* 0x09 */ + OR, aohand, 2, 4, /* 0x0a */ + OR, aohand, 2, 4, /* 0x0b */ + OR, aohand, 2, 2, /* 0x0c */ + OR, aohand, 3, 3, /* 0x0d */ + "\tpush\tcs", sbhand, 1, 1, /* 0x0e */ + NULL, dfhand, 0, 0, /* 0x0f */ + ADC, aohand, 2, 4, /* 0x10 */ + ADC, aohand, 2, 4, /* 0x11 */ + ADC, aohand, 2, 4, /* 0x12 */ + ADC, aohand, 2, 4, /* 0x13 */ + ADC, aohand, 2, 2, /* 0x14 */ + ADC, aohand, 3, 3, /* 0x15 */ + "\tpush\tss", sbhand, 1, 1, /* 0x16 */ + "\tpop\tss", sbhand, 1, 1, /* 0x17 */ + SBB, aohand, 2, 4, /* 0x18 */ + SBB, aohand, 2, 4, /* 0x19 */ + SBB, aohand, 2, 4, /* 0x1a */ + SBB, aohand, 2, 4, /* 0x1b */ + SBB, aohand, 2, 2, /* 0x1c */ + SBB, aohand, 3, 3, /* 0x1d */ + "\tpush\tds", sbhand, 1, 1, /* 0x1e */ + "\tpop\tds", sbhand, 1, 1, /* 0x1f */ + AND, aohand, 2, 4, /* 0x20 */ + AND, aohand, 2, 4, /* 0x21 */ + AND, aohand, 2, 4, /* 0x22 */ + AND, aohand, 2, 4, /* 0x23 */ + AND, aohand, 2, 2, /* 0x24 */ + AND, aohand, 3, 3, /* 0x25 */ + "\tseg\tes", sbhand, 1, 1, /* 0x26 */ + "\tdaa", sbhand, 1, 1, /* 0x27 */ + SUB, aohand, 2, 4, /* 0x28 */ + SUB, aohand, 2, 4, /* 0x29 */ + SUB, aohand, 2, 4, /* 0x2a */ + SUB, aohand, 2, 4, /* 0x2b */ + SUB, aohand, 2, 2, /* 0x2c */ + SUB, aohand, 3, 3, /* 0x2d */ + "\tseg\tcs", sbhand, 1, 1, /* 0x2e */ + "\tdas", sbhand, 1, 1, /* 0x2f */ + XOR, aohand, 2, 4, /* 0x30 */ + XOR, aohand, 2, 4, /* 0x31 */ + XOR, aohand, 2, 4, /* 0x32 */ + XOR, aohand, 2, 4, /* 0x33 */ + XOR, aohand, 2, 2, /* 0x34 */ + XOR, aohand, 3, 3, /* 0x35 */ + "\tseg\tss", sbhand, 1, 1, /* 0x36 */ + "\taaa", sbhand, 1, 1, /* 0x37 */ + CMP, aohand, 2, 4, /* 0x38 */ + CMP, aohand, 2, 4, /* 0x39 */ + CMP, aohand, 2, 4, /* 0x3a */ + CMP, aohand, 2, 4, /* 0x3b */ + CMP, aohand, 2, 2, /* 0x3c */ + CMP, aohand, 3, 3, /* 0x3d */ + "\tseg\tds", sbhand, 1, 1, /* 0x3e */ + "\taas", sbhand, 1, 1, /* 0x3f */ + "\tinc\tax", sbhand, 1, 1, /* 0x40 */ + "\tinc\tcx", sbhand, 1, 1, /* 0x41 */ + "\tinc\tdx", sbhand, 1, 1, /* 0x42 */ + "\tinc\tbx", sbhand, 1, 1, /* 0x43 */ + "\tinc\tsp", sbhand, 1, 1, /* 0x44 */ + "\tinc\tbp", sbhand, 1, 1, /* 0x45 */ + "\tinc\tsi", sbhand, 1, 1, /* 0x46 */ + "\tinc\tdi", sbhand, 1, 1, /* 0x47 */ + "\tdec\tax", sbhand, 1, 1, /* 0x48 */ + "\tdec\tcx", sbhand, 1, 1, /* 0x49 */ + "\tdec\tdx", sbhand, 1, 1, /* 0x4a */ + "\tdec\tbx", sbhand, 1, 1, /* 0x4b */ + "\tdec\tsp", sbhand, 1, 1, /* 0x4c */ + "\tdec\tbp", sbhand, 1, 1, /* 0x4d */ + "\tdec\tsi", sbhand, 1, 1, /* 0x4e */ + "\tdec\tdi", sbhand, 1, 1, /* 0x4f */ + "\tpush\tax", sbhand, 1, 1, /* 0x50 */ + "\tpush\tcx", sbhand, 1, 1, /* 0x51 */ + "\tpush\tdx", sbhand, 1, 1, /* 0x52 */ + "\tpush\tbx", sbhand, 1, 1, /* 0x53 */ + "\tpush\tsp", sbhand, 1, 1, /* 0x54 */ + "\tpush\tbp", sbhand, 1, 1, /* 0x55 */ + "\tpush\tsi", sbhand, 1, 1, /* 0x56 */ + "\tpush\tdi", sbhand, 1, 1, /* 0x57 */ + "\tpop\tax", sbhand, 1, 1, /* 0x58 */ + "\tpop\tcx", sbhand, 1, 1, /* 0x59 */ + "\tpop\tdx", sbhand, 1, 1, /* 0x5a */ + "\tpop\tbx", sbhand, 1, 1, /* 0x5b */ + "\tpop\tsp", sbhand, 1, 1, /* 0x5c */ + "\tpop\tbp", sbhand, 1, 1, /* 0x5d */ + "\tpop\tsi", sbhand, 1, 1, /* 0x5e */ + "\tpop\tdi", sbhand, 1, 1, /* 0x5f */ + NULL, dfhand, 0, 0, /* 0x60 */ + NULL, dfhand, 0, 0, /* 0x61 */ + NULL, dfhand, 0, 0, /* 0x62 */ + NULL, dfhand, 0, 0, /* 0x63 */ + NULL, dfhand, 0, 0, /* 0x64 */ + NULL, dfhand, 0, 0, /* 0x65 */ + NULL, dfhand, 0, 0, /* 0x66 */ + NULL, dfhand, 0, 0, /* 0x67 */ + NULL, dfhand, 0, 0, /* 0x68 */ + NULL, dfhand, 0, 0, /* 0x69 */ + NULL, dfhand, 0, 0, /* 0x6a */ + NULL, dfhand, 0, 0, /* 0x6b */ + NULL, dfhand, 0, 0, /* 0x6c */ + NULL, dfhand, 0, 0, /* 0x6d */ + NULL, dfhand, 0, 0, /* 0x6e */ + NULL, dfhand, 0, 0, /* 0x6f */ + "\tjo", sjhand, 2, 2, /* 0x70 */ + "\tjno", sjhand, 2, 2, /* 0x71 */ + "\tjc", sjhand, 2, 2, /* 0x72 */ + "\tjnc", sjhand, 2, 2, /* 0x73 */ + "\tjz", sjhand, 2, 2, /* 0x74 */ + "\tjnz", sjhand, 2, 2, /* 0x75 */ + "\tjna", sjhand, 2, 2, /* 0x76 */ + "\tja", sjhand, 2, 2, /* 0x77 */ + "\tjs", sjhand, 2, 2, /* 0x78 */ + "\tjns", sjhand, 2, 2, /* 0x79 */ + "\tjp", sjhand, 2, 2, /* 0x7a */ + "\tjnp", sjhand, 2, 2, /* 0x7b */ + "\tjl", sjhand, 2, 2, /* 0x7c */ + "\tjnl", sjhand, 2, 2, /* 0x7d */ + "\tjng", sjhand, 2, 2, /* 0x7e */ + "\tjg", sjhand, 2, 2, /* 0x7f */ + AMBIG, imhand, 3, 5, /* 0x80 */ + AMBIG, imhand, 4, 6, /* 0x81 */ + AMBIG, imhand, 3, 5, /* 0x82 */ + AMBIG, imhand, 3, 5, /* 0x83 */ + TEST, mvhand, 2, 4, /* 0x84 */ + TEST, mvhand, 2, 4, /* 0x85 */ + "\txchg", mvhand, 2, 4, /* 0x86 */ + "\txchg", mvhand, 2, 4, /* 0x87 */ + MOV, mvhand, 2, 4, /* 0x88 */ + MOV, mvhand, 2, 4, /* 0x89 */ + MOV, mvhand, 2, 4, /* 0x8a */ + MOV, mvhand, 2, 4, /* 0x8b */ + MOV, mshand, 2, 4, /* 0x8c */ + "\tlea", mvhand, 2, 4, /* 0x8d */ + MOV, mshand, 2, 4, /* 0x8e */ + "\tpop", pohand, 2, 4, /* 0x8f */ + "\tnop", sbhand, 1, 1, /* 0x90 */ + "\txchg\tax,cx", sbhand, 1, 1, /* 0x91 */ + "\txchg\tax,dx", sbhand, 1, 1, /* 0x92 */ + "\txchg\tax,bx", sbhand, 1, 1, /* 0x93 */ + "\txchg\tax,sp", sbhand, 1, 1, /* 0x94 */ + "\txchg\tax,bp", sbhand, 1, 1, /* 0x95 */ + "\txchg\tax,si", sbhand, 1, 1, /* 0x96 */ + "\txchg\tax,di", sbhand, 1, 1, /* 0x97 */ + "\tcbw", sbhand, 1, 1, /* 0x98 */ + "\tcwd", sbhand, 1, 1, /* 0x99 */ + "\tcalli", cihand, 5, 5, /* 0x9a */ + "\twait", sbhand, 1, 1, /* 0x9b */ + "\tpushf", sbhand, 1, 1, /* 0x9c */ + "\tpopf", sbhand, 1, 1, /* 0x9d */ + "\tsahf", sbhand, 1, 1, /* 0x9e */ + "\tlahf", sbhand, 1, 1, /* 0x9f */ + MOV, mqhand, 3, 3, /* 0xa0 */ + MOV, mqhand, 3, 3, /* 0xa1 */ + MOV, mqhand, 3, 3, /* 0xa2 */ + MOV, mqhand, 3, 3, /* 0xa3 */ + "\tmovb", sbhand, 1, 1, /* 0xa4 */ + "\tmovw", sbhand, 1, 1, /* 0xa5 */ + "\tcmpb", sbhand, 1, 1, /* 0xa6 */ + "\tcmpw", sbhand, 1, 1, /* 0xa7 */ + TEST, tqhand, 2, 2, /* 0xa8 */ + TEST, tqhand, 3, 3, /* 0xa9 */ + "\tstob", sbhand, 1, 1, /* 0xaa */ + "\tstow", sbhand, 1, 1, /* 0xab */ + "\tlodb", sbhand, 1, 1, /* 0xac */ + "\tlodw", sbhand, 1, 1, /* 0xad */ + "\tscab", sbhand, 1, 1, /* 0xae */ + "\tscaw", sbhand, 1, 1, /* 0xaf */ + "\tmov\tal,", mihand, 2, 2, /* 0xb0 */ + "\tmov\tcl,", mihand, 2, 2, /* 0xb1 */ + "\tmov\tdl,", mihand, 2, 2, /* 0xb2 */ + "\tmov\tbl,", mihand, 2, 2, /* 0xb3 */ + "\tmov\tah,", mihand, 2, 2, /* 0xb4 */ + "\tmov\tch,", mihand, 2, 2, /* 0xb5 */ + "\tmov\tdh,", mihand, 2, 2, /* 0xb6 */ + "\tmov\tbh,", mihand, 2, 2, /* 0xb7 */ + "\tmov\tax,", mihand, 3, 3, /* 0xb8 */ + "\tmov\tcx,", mihand, 3, 3, /* 0xb9 */ + "\tmov\tdx,", mihand, 3, 3, /* 0xba */ + "\tmov\tbx,", mihand, 3, 3, /* 0xbb */ + "\tmov\tsp,", mihand, 3, 3, /* 0xbc */ + "\tmov\tbp,", mihand, 3, 3, /* 0xbd */ + "\tmov\tsi,", mihand, 3, 3, /* 0xbe */ + "\tmov\tdi,", mihand, 3, 3, /* 0xbf */ + NULL, dfhand, 0, 0, /* 0xc0 */ + NULL, dfhand, 0, 0, /* 0xc1 */ + "\tret", rehand, 3, 3, /* 0xc2 */ + "\tret", sbhand, 1, 1, /* 0xc3 */ + "\tles", mvhand, 2, 4, /* 0xc4 */ + "\tlds", mvhand, 2, 4, /* 0xc5 */ + MOV, mmhand, 3, 5, /* 0xc6 */ + MOV, mmhand, 4, 6, /* 0xc7 */ + NULL, dfhand, 0, 0, /* 0xc8 */ + NULL, dfhand, 0, 0, /* 0xc9 */ + "\treti", rehand, 3, 3, /* 0xca */ + "\treti", sbhand, 1, 1, /* 0xcb */ + "\tint", sbhand, 1, 1, /* 0xcc */ + "\tint", inhand, 2, 2, /* 0xcd */ + "\tinto", sbhand, 1, 1, /* 0xce */ + "\tiret", sbhand, 1, 1, /* 0xcf */ + AMBIG, srhand, 2, 4, /* 0xd0 */ + AMBIG, srhand, 2, 4, /* 0xd1 */ + AMBIG, srhand, 2, 4, /* 0xd2 */ + AMBIG, srhand, 2, 4, /* 0xd3 */ + "\taam", aahand, 2, 2, /* 0xd4 */ + "\taad", aahand, 2, 2, /* 0xd5 */ + NULL, dfhand, 0, 0, /* 0xd6 */ + "\txlat", sbhand, 1, 1, /* 0xd7 */ + ESC, eshand, 2, 2, /* 0xd8 */ + ESC, eshand, 2, 2, /* 0xd9 */ + ESC, eshand, 2, 2, /* 0xda */ + ESC, eshand, 2, 2, /* 0xdb */ + ESC, eshand, 2, 2, /* 0xdc */ + ESC, eshand, 2, 2, /* 0xdd */ + ESC, eshand, 2, 2, /* 0xde */ + ESC, eshand, 2, 2, /* 0xdf */ + "\tloopne", sjhand, 2, 2, /* 0xe0 */ + "\tloope", sjhand, 2, 2, /* 0xe1 */ + "\tloop", sjhand, 2, 2, /* 0xe2 */ + "\tjcxz", sjhand, 2, 2, /* 0xe3 */ + "\tin", iohand, 2, 2, /* 0xe4 */ + "\tinw", iohand, 2, 2, /* 0xe5 */ + "\tout", iohand, 2, 2, /* 0xe6 */ + "\toutw", iohand, 2, 2, /* 0xe7 */ + "\tcall", ljhand, 3, 3, /* 0xe8 */ + "\tjmp", ljhand, 3, 3, /* 0xe9 */ + "\tjmpi", cihand, 5, 5, /* 0xea */ + "\tj", sjhand, 2, 2, /* 0xeb */ + "\tin", sbhand, 1, 1, /* 0xec */ + "\tinw", sbhand, 1, 1, /* 0xed */ + "\tout", sbhand, 1, 1, /* 0xee */ + "\toutw", sbhand, 1, 1, /* 0xef */ + "\tlock", sbhand, 1, 1, /* 0xf0 */ + NULL, dfhand, 0, 0, /* 0xf1 */ + "\trepnz", sbhand, 1, 1, /* 0xf2 */ + "\trepz", sbhand, 1, 1, /* 0xf3 */ + "\thlt", sbhand, 1, 1, /* 0xf4 */ + "\tcmc", sbhand, 1, 1, /* 0xf5 */ + AMBIG, mahand, 2, 5, /* 0xf6 */ + AMBIG, mahand, 2, 6, /* 0xf7 */ + "\tclc", sbhand, 1, 1, /* 0xf8 */ + "\tstc", sbhand, 1, 1, /* 0xf9 */ + "\tcli", sbhand, 1, 1, /* 0xfa */ + "\tsti", sbhand, 1, 1, /* 0xfb */ + "\tcld", sbhand, 1, 1, /* 0xfc */ + "\tstd", sbhand, 1, 1, /* 0xfd */ + AMBIG, mjhand, 2, 4, /* 0xfe */ + AMBIG, mjhand, 2, 4 /* 0xff */ + }; + + /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * * + * This simple routine returns the name field of a symbol * + * table entry as a printable string. * + * * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +char * +getnam(k) + + register int k; + +{/* * * * * * * * * * START OF getnam() * * * * * * * * * */ + + register int j; + static char a[sizeof(symtab->n_name)+1]; + + for (j = 0; j < sizeof(symtab[k].n_name); ++j) + if ( ! symtab[k].n_name[j] ) + break; + else + a[j] = symtab[k].n_name[j]; + + a[j] = '\0'; + + return (a); + +}/* * * * * * * * * * * END OF getnam() * * * * * * * * * * */ + + /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * * + * This function is responsible for mucking through the * + * relocation table in search of externally referenced * + * symbols to be output as operands. It accepts two long * + * arguments: the code-segment location at which an extern * + * reference is expected, and the offset value which is * + * embedded in the object code and used at link time to * + * bias the external value. In the most typical case, the * + * function will be called by lookup(), which always makes * + * a check for external names before searching the symbol * + * table proper. However, it may also be called directly * + * by any function (such as the move-immediate handler) * + * which wants to make an independent check for externals. * + * The caller is expected to supply, as the third argument * + * to the function, a pointer to a character buffer large * + * enough to hold any possible output string. Lookext() * + * will fill this buffer and return a logical TRUE if it * + * finds an extern reference; otherwise, it will return a * + * logical FALSE, leaving the buffer undisturbed. * + * * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +int +lookext(off,loc,buf) + + long off, loc; + char *buf; + +{/* * * * * * * * * * START OF lookext() * * * * * * * * * */ + + register int k; + char c[32]; + + if ((loc != -1L) && (relptr >= 0)) + for (k = 0; k <= relptr; ++k) + if ((relo[k].r_vaddr == loc) + && (relo[k].r_symndx < S_BSS)) + { + strcpy(buf,getnam(relo[k].r_symndx)); + if (off) + { + if (off < 0) + sprintf(c,"%ld",off); + else + sprintf(c,"+%ld",off); + strcat(buf,c); + } + return (1); + } + + return (0); + +}/* * * * * * * * * * END OF lookext() * * * * * * * * * */ + + /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * * + * This function finds an entry in the symbol table by * + * value. Its input is a (long) machine address, and its * + * output is a pointer to a string containing the corre- * + * sponding symbolic name. The function first searches the * + * relocation table for a possible external reference; if * + * none is found, a linear search of the symbol table is * + * undertaken. If no matching symbol has been found at the * + * end of these searches, the function returns a pointer * + * to a string containing the ASCII equivalent of the ad- * + * dress which was to be located, so that, regardless of * + * the success of the search, the function's return value * + * is suitable for use as a memory-reference operand. The * + * caller specifies the type of symbol to be found (text, * + * data, bss, undefined, absolute, or common) by means of * + * the function's second parameter. The third parameter * + * specifies the format to be used in the event of a nu- * + * meric output: zero for absolute format, one for short * + * relative format, two for long relative format. The * + * fourth parameter is the address which would appear in * + * the relocation table for the reference in question, or * + * -1 if the relocation table is not to be searched. The * + * function attempts to apply a certain amount of intelli- * + * gence in its selection of symbols, so it is possible * + * that, in the absence of a type match, a symbol of the * + * correct value but different type will be returned. * + * * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +char * +lookup(addr,type,kind,ext) + + long addr; /* Machine address to be located */ + + int type, /* Type of symbol to be matched */ + kind; /* Addressing output mode to use */ + + long ext; /* Value for extern ref, if any */ + +{/* * * * * * * * * * START OF lookup() * * * * * * * * * */ + + register int j, k; + static char b[80]; + + struct + { + int i; + int t; + } + best; + + if (lookext(addr,ext,b)) + return (b); + + if (segflg) + if (segflg & 1) + type = N_TEXT; + else + type = N_DATA; + + for (k = 0, best.i = -1; k <= symptr; ++k) + if (symtab[k].n_value == addr) + if ((j = symtab[k].n_sclass & N_SECT) == type) + { + best.t = j; + best.i = k; + break; + } + else if (segflg || (HDR.a_flags & A_SEP)) + continue; + else if (best.i < 0) + best.t = j, best.i = k; + else if (symrank[type][j] > symrank[type][best.t]) + best.t = j, best.i = k; + + if (best.i >= 0) + return (getnam(best.i)); + + if (kind == LOOK_ABS) + sprintf(b,"0x%05.5x",addr); + else + { + long x = addr - (PC - kind); + if (x < 0) + sprintf(b,".%ld",x); + else + sprintf(b,".+%ld",x); + } + + return (b); + +}/* * * * * * * * * * * END OF lookup() * * * * * * * * * * */ + + /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * * + * This function translates an 8088 addressing mode byte * + * to an equivalent assembler string, returning a pointer * + * thereto. If necessary, it performs successive inputs * + * of bytes from the object file in order to obtain offset * + * data, adjusting PC accordingly. (The addressing mode * + * byte appears in several 8088 opcodes; it is used to * + * specify source and destination operand locations.) The * + * third argument to the function is zero if the standard * + * registers are to be used, or eight if the segment reg- * + * isters are to be used; these constants are defined sym- * + * bolically in dis.h. NOTE: The mtrans() function must * + * NEVER be called except immediately after fetching the * + * mode byte. If any additional object bytes are fetched * + * after the fetch of the mode byte, mtrans() will not * + * produce correct output! * + * * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +char * +mtrans(c,m,type) + + register int c; /* Primary instruction byte */ + register int m; /* Addressing mode byte */ + + int type; /* Type code: standard or seg */ + +{/* * * * * * * * * * START OF mtrans() * * * * * * * * * */ + + unsigned long pc; + int offset, oflag, dir, w, mod, reg, rm; + static char a[100]; + static char b[30]; + + offset = 0; + dir = c & 2; + w = c & 1; + mod = (m & 0xc0) >> 6; + reg = (m & 0x38) >> 3; + rm = m & 7; + pc = PC + 1; + + if (type) + w = 1; + + if ((oflag = mod) > 2) + oflag = 0; + + if (oflag) + { + int j, k; + if (oflag == 2) + { + FETCH(j); + FETCH(k); + offset = (k << 8) | j; + } + else + { + FETCH(j); + if (j & 0x80) + k = 0xff00; + else + k = 0; + offset = k | j; + } + } + + if (dir) + { + strcpy(a,REGS[type + ((w << 3) | reg)]); + strcat(a,","); + switch (mod) + { + case 0 : + if (rm == 6) + { + int j, k; + FETCH(j); + FETCH(k); + offset = (k << 8) | j; + strcat(a, + lookup((long)(offset),N_DATA,LOOK_ABS,pc)); + } + else + { + sprintf(b,"(%s)",REGS0[rm]); + strcat(a,b); + } + break; + case 1 : + case 2 : + if (mod == 1) + strcat(a,"*"); + else + strcat(a,"#"); + sprintf(b,"%d(",offset); + strcat(a,b); + strcat(a,REGS1[rm]); + strcat(a,")"); + break; + case 3 : + strcat(a,REGS[(w << 3) | rm]); + break; + } + } + else + { + switch (mod) + { + case 0 : + if (rm == 6) + { + int j, k; + FETCH(j); + FETCH(k); + offset = (k << 8) | j; + strcpy(a, + lookup((long)(offset),N_DATA,LOOK_ABS,pc)); + } + else + { + sprintf(b,"(%s)",REGS0[rm]); + strcpy(a,b); + } + break; + case 1 : + case 2 : + if (mod == 1) + strcpy(a,"*"); + else + strcpy(a,"#"); + sprintf(b,"%d(",offset); + strcat(a,b); + strcat(a,REGS1[rm]); + strcat(a,")"); + break; + case 3 : + strcpy(a,REGS[(w << 3) | rm]); + break; + } + strcat(a,","); + strcat(a,REGS[type + ((w << 3) | reg)]); + } + + return (a); + +}/* * * * * * * * * * * END OF mtrans() * * * * * * * * * * */ + + /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * * + * This simple routine truncates a string returned by the * + * mtrans() function, removing its source operand. This is * + * useful in handlers which ignore the "reg" field of the * + * mode byte. * + * * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +void +mtrunc(a) + + register char *a; /* Ptr. to string to truncate */ + +{/* * * * * * * * * * START OF mtrunc() * * * * * * * * * */ + + register int k; + + for (k = strlen(a) - 1; k >= 0; --k) + if (a[k] == ',') + { + a[k] = '\0'; + break; + } + +}/* * * * * * * * * * * END OF mtrunc() * * * * * * * * * * */ + + |