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

📄 dishand.c

📁 操作系统源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
static char *sccsid =   "@(#) dishand.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 source code for most of the spe- *  * cialized handler routines of the disassembler  program. *  * (The file disfp.c contains handler routines specific to *  * the 8087 numeric  co-processor.)  Each handler  routine *  * interprets the opcode byte  (and subsequent data bytes, *  * if any)  of a particular family of opcodes,  and is re- *  * sponsible for generating appropriate output. All of the *  * code in this file is highly MACHINE-SPECIFIC, and would *  * have to be rewritten for a different  CPU.  The handler *  * routines are accessed  only via pointers in the optab[] *  * array, however, so machine dependencies are confined to *  * this file, its sister file "disfp.c", and the data file *  * "distabs.c".                                            *  *                                                         *  * All of the code in this file is based on the assumption *  * of sixteen-bit integers.                                *  *                                                         *  * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */#include "dis.h"              /* Disassembler declarations  */int segflg;                   /* Segment-override flag      */unsigned char objbuf[OBJMAX]; /* Buffer for object code     */int objptr;                   /* Index into objbuf[]        */unsigned long PC;             /* Current program counter    */ /* * * * * *  MISCELLANEOUS SUPPORTING ROUTINES  * * * * * */voidobjini(j)                     /* Object code init routine   */   register int j;{   if ((segflg == 1) || (segflg == 2))      segflg *= 3;   else      segflg = 0;   objptr = 0;   objbuf[objptr++] = (unsigned char)(j);}voidobjout()                      /* Object-code output routine */{    register int k;   if ( ! objflg )      return;   else      {      printf("\t|");      if (symptr >= 0)         printf(" %05.5lx:",(PC + 1L - (long)(objptr)));      for (k = 0; k < objptr; ++k)         printf(" %02.2x",objbuf[k]);      putchar('\n');      }}voidbadseq(j,k)                   /* Invalid-sequence routine   */   register int j, k;{   printf("\t.byte\t0x%02.2x\t\t| invalid code sequence\n",j);   printf("\t.byte\t0x%02.2x\n",k);} /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * *  *                                                         *  * This  routine  is the first of several  opcode-specific *  * handlers,  each of which is  dedicated  to a particular *  * opcode family.  A pointer to a handler  routine is con- *  * tained in the second field of each optab[]  entry.  The *  * dfhand()  routine is the default handler,  invoked when *  * no other handler is appropriate (generally, when an in- *  * valid opcode is encountered).                           *  *                                                         *  * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */voiddfhand(j)   register int j;            /* Pointer to optab[] entry   */{/* * * * * * * * * *  START OF dfhand()  * * * * * * * * * */   segflg = 0;   printf("\t.byte\t0x%02.2x",j);   if (optab[j].min || optab[j].max)      putchar('\n');   else      printf("\t\t| unimplemented opcode\n");}/* * * * * * * * * * * END OF dfhand() * * * * * * * * * * */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * *  *                                                         *  * This is the  single-byte  handler,  invoked  whenever a *  * one-byte opcode is encountered.                         *  *                                                         *  * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */voidsbhand(j)   register int j;            /* Pointer to optab[] entry   */{/* * * * * * * * * *  START OF sbhand()  * * * * * * * * * */   objini(j);   if (j == 0x2e)                               /* seg cs   */      segflg = 1;   if ((j == 0x26)                              /* seg es   */    || (j == 0x36)                              /* seg ss   */    || (j == 0x3e))                             /* seg ds   */      segflg = 2;   printf("%s\n",optab[j].text);   objout();}/* * * * * * * * * * * END OF sbhand() * * * * * * * * * * */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * *  *                                                         *  * This is the handler for most of the processor's regular *  * arithmetic operations.                                  *  *                                                         *  * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */voidaohand(j)   register int j;            /* Pointer to optab[] entry   */{/* * * * * * * * * *  START OF aohand()  * * * * * * * * * */   register int k;   int m, n;   char b[64];   objini(j);   switch (j & 7)      {      case 0 :      case 1 :      case 2 :      case 3 :         printf("%s\t",optab[j].text);         FETCH(k);         printf("%s\n",mtrans(j,k,TR_STD));         break;      case 4 :         FETCH(k);         printf("%s\tal,*0x%02.2x\n",optab[j].text,k);         break;      case 5 :         FETCH(m);         FETCH(n);         k = (n << 8) | m;         if (lookext((long)(k),(PC - 1),b))            printf("%s\tax,#%s\n",optab[j].text,b);         else            printf("%s\tax,#0x%04.4x\n",optab[j].text,k);         break;      default :         dfhand(j);         break;      }   objout();}/* * * * * * * * * * * END OF aohand() * * * * * * * * * * */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * *  *                                                         *  * This is the  handler for opcodes  which  perform  short *  * (eight-bit) relative jumps.                             *  *                                                         *  * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */voidsjhand(j)   register int j;            /* Pointer to optab[] entry   */{/* * * * * * * * * *  START OF sjhand()  * * * * * * * * * */   register int k;   int m;   objini(j);   FETCH(m);   if (m & 0x80)      k = 0xff00;   else      k = 0;   k |= m;   printf("%s\t%s\t\t| loc %05.5lx\n",optab[j].text,    lookup((PC + k + 1L),N_TEXT,LOOK_REL,-1L),    (PC + k + 1L));   objout();}/* * * * * * * * * * * END OF sjhand() * * * * * * * * * * */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * *  *                                                         *  * This is the  handler for a  loosely-knit  family of op- *  * codes which perform  arithmetic and logical operations, *  * and which take immediate  data.  The routine's logic is *  * rather complex,  so,  in an effort to avoid  additional *  * complexity,  the search for external  references in the *  * relocation table has been dispensed with. Eager hackers *  * can try their hand at coding such a search.             *  *                                                         *  * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */voidimhand(j)   register int j;            /* Pointer to optab[] entry   */{/* * * * * * * * * *  START OF imhand()  * * * * * * * * * */   unsigned long pc;   register int k;   int offset, oflag, immed, iflag, mod, opi, w, rm;   int m, n;   static char a[100], b[30];   objini(j);   FETCH(k);   pc = PC + 1;   offset = 0;   mod = (k & 0xc0) >> 6;   opi = (k & 0x38) >> 3;   w = j & 1;   rm = k & 7;   if ((j & 2)    && ((opi == 1)     || (opi == 4)     || (opi == 6)))      {      badseq(j,k);      return;      }   strcpy(a,OPFAM[opi]);   if ( ! w )      strcat(a,"b");   if ((oflag = mod) > 2)      oflag = 0;   if ((mod == 0) && (rm == 6))      {      FETCH(m);      FETCH(n);      offset = (n << 8) | m;      }   else if (oflag)      if (oflag == 2)         {         FETCH(m);         FETCH(n);         offset = (n << 8) | m;         }      else         {         FETCH(m);         if (m & 0x80)            n = 0xff00;         else            n = 0;         offset = n | m;         }   switch (j & 3)      {      case 0 :      case 2 :         FETCH(immed);         iflag = 0;         break;      case 1 :         FETCH(m);         FETCH(n);         immed = (n << 8) | m;         iflag = 1;         break;      case 3 :         FETCH(immed);         if (immed & 0x80)            immed &= 0xff00;         iflag = 0;         break;      }   strcat(a,"\t");   switch (mod)      {      case 0 :         if (rm == 6)            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;      }   strcat(a,",");   if (iflag)      strcat(a,"#");   else      strcat(a,"*");   sprintf(b,"%d",immed);   strcat(a,b);   printf("%s\n",a);   objout();}/* * * * * * * * * * * END OF imhand() * * * * * * * * * * */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * *  *                                                         *  * This is the  handler  for  various  "mov"-type  opcodes *  * which use the mod,  reg,  and r/m  fields of the second *  * code byte in a standard, straightforward way.           *  *                                                         *  * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */voidmvhand(j)   int j;                     /* Pointer to optab[] entry   */{/* * * * * * * * * *  START OF mvhand()  * * * * * * * * * */   register int k, m = j;   objini(j);   FETCH(k);   if ((m == 0x84) || (m == 0x85)      /* Kind of kludgey   */    || (m == 0xc4) || (m == 0xc5)    || (m == 0x8d))      if (m & 0x40)         m |= 0x03;      else         m |= 0x02;   printf("%s\t%s\n",optab[j].text,mtrans(m,k,TR_STD));   objout();}/* * * * * * * * * * * END OF mvhand() * * * * * * * * * * */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * *  *                                                         *  * This is the handler for segment-register "mov" opcodes. *  *                                                         *  * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */voidmshand(j)   register int j;            /* Pointer to optab[] entry   */{/* * * * * * * * * *  START OF mshand()  * * * * * * * * * */   register int k;   objini(j);   FETCH(k);   if (k & 0x20)      {      badseq(j,k);      return;      }   printf("%s\t%s\n",optab[j].text,mtrans(j,k,TR_SEG));   objout();}/* * * * * * * * * * * END OF mshand() * * * * * * * * * * */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * *  *                                                         *  * This is the  handler for pops,  other than  single-byte *  * pops.  (The 8088 allows  popping into any register,  or *  * directly into memory,  accessed  either  immediately or *  * through a register and an index.)                       *  *                                                         *  * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */voidpohand(j)   register int j;            /* Pointer to optab[] entry   */{/* * * * * * * * * *  START OF pohand()  * * * * * * * * * */   char *a;   register int k;   objini(j);   FETCH(k);   if (k & 0x38)      {      badseq(j,k);      return;      }   printf("%s\t",optab[j].text);   a = mtrans((j & 0xfd),k,TR_STD);   mtrunc(a);   printf("%s\n",a);   objout();}/* * * * * * * * * * * END OF pohand() * * * * * * * * * * */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * *  *                                                         *  * This is the handler routine for intersegment  calls and *  * jumps.  Its output is never symbolic,  because the host *  * linker  does not allow  symbolic  intersegment  address *  * references except by means of symbolic  constants,  and *  * any such  constants in the symbol  table,  even if they *  * are of the  appropriate  value,  may be misleading.  In *  * compiled code,  intersegment  references  should not be *  * encountered,  and even in assembled  code,  they should *  * occur infrequently. If and when they do occur, however, *  * they will be disassembled in absolute form.             *  *                                                         *  * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */voidcihand(j)   int j;                     /* Pointer to optab[] entry   */{/* * * * * * * * * *  START OF cihand()  * * * * * * * * * */   register int m, n;   objini(j);   printf("%s\t",optab[j].text);   FETCH(m);   FETCH(n);   printf("#0x%04.4x,",((n << 8) | m));   FETCH(m);   FETCH(n);   printf("#0x%04.4x\n",((n << 8) | m));   objout();

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -