708 lines
30 KiB
C
708 lines
30 KiB
C
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[9];
|
||
|
||
for (j = 0; j < 8; ++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[16];
|
||
|
||
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[64];
|
||
|
||
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() * * * * * * * * * * */
|
||
|
||
|