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

📄 distabs.c

📁 操作系统源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
  * 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 + -