📄 distabs.c
字号:
* 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. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */intlookext(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. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */voidmtrunc(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() * * * * * * * * * * */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -