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

📄 masmber_c3.cpp

📁 MCS51单片机的宏汇编器源程序。有需要的朋友请下载!
💻 CPP
📖 第 1 页 / 共 3 页
字号:
{ ERR err;
  bool temp = Pass; Pass = true; // 暂存Pass内容。
  // 尝试计算数值表达式,忽略一部分错误。
  const TriVal* t = LabMger->CalExpression(err, pt->ExpPt->ExpPt); // 给TriVal赋值
  Pass = temp;                   // 恢复Pass内容。

  if(err)
   { if(err != LabNotReady || t == NULL) { return; } // endif
   } // endif
  if(t->fix || t->rel == 'E') { return; } // endif
  if(    t->rseg == NULL && Ln->sgpt != JModulePt->GetAbsCodeSeg()
      || t->rseg != NULL && Ln->sgpt != t->rseg ) { return; } // endif

  int32 rel = t->val - Ln->lc - 2;
  switch(opset->OPnum)
  { case JMP :
     { if(AddrInPage(rel))               // SJMP label
        { opset = InstSystem::OpSJMP(); } // endif
       else if(AddrInBlock(rel))         // AJMP label
        { opset = InstSystem::OpAJMP(); } // end elseif
       else
        { //opset = InstSystem::OpLJMP();
        } // end else
       break;
     } // end case
    case CALL:
     { if(AddrInBlock(rel))              // ACALL label
        { opset = InstSystem::OpACALL(); } // endif
       else
        { //opset = InstSystem::OpLCALL();
        } // end else
       break;
     } // end case
    // no default.
  } // end switch
} // end RecgJMPandCALL
//---------------------------------------------------------------------------

//---------------------------------------------------------------------------
// 分析该条指令的各个操作数的寻址方式. 返回匹配的OPset*指针.
// pt 应指向一个操作码保留字, 即 pt->Token == ReservInst
// err = 1, 第一操作数错误。
// err = 2, 第二操作数错误。
// err = 3, 第三操作数错误。
// 如果匹配方式错误,返回NULL。
//---------------------------------------------------------------------------
OPset* MacroAsmber::FindResvInstOPset(Tokenfield* pt, ERR &err)
{ err = 0;          // 对err值清零
  int8u OPR[4];
    // 识别操作码的Token
  OPR[0] = (int8u)pt->Token2;   // 截去它的高8位, 留下低8位
  Tokenfield* t = pt->next;          // t 指向第一个操作数

  for(int8u n = 1; n < 4; n++)       // n 是操作数序号
   { if( t )       // 如果他不为空, 也就是说有操作数
      { OPR[n] = GetDataType(t);     // t->Token == Operand
                   // GetDataType()返回寻址方式Token。出错返回零。
        if(OPR[n] == 0)     // 如果有错(OPR[n]==0)
         { err = n; OutputErr(WrongOperandsErr+n-1);
           return NULL;
         } // endif

        t = t->next;    // t 指向下一个操作数
      } // endif
     else          // t == NULL
      { OPR[n] = -1; }      // 缺省值 0xff
   } // end for

  // 至此, OPR[]已经设置好。可以进行OPset比较。找不到返回NULL。
  return Instm->OPsetRecg(OPR[0], OPR[1], OPR[2], OPR[3]);
} // end FindResvInstOPset
//---------------------------------------------------------------------------

//---------------------------------------------------------------------------
#define indirect_REG  switch(t->val)                                            \
                      { case _R0  : return _aR0;                                \
                        case _R1  : return _aR1;                                \
                        case _DPTR: return _aDPTR;                              \
                        case _A_DPTR:return _aA_DPTR;                           \
                        case _A_PC: return _aA_PC;                              \
                        default   : return 0;                                   \
                      }
//---------------------------------------------------------------------------
#define Only_1_REG    switch(t->val)                                            \
                      { case _A  : return _A;                                   \
                        case _R0 : return _R0;                                  \
                        case _R1 : return _R1;                                  \
                        case _R2 : return _R2;                                  \
                        case _R3 : return _R3;                                  \
                        case _R4 : return _R4;                                  \
                        case _R5 : return _R5;                                  \
                        case _R6 : return _R6;                                  \
                        case _R7 : return _R7;                                  \
                        case _DPTR:return _DPTR;                                \
                        case _C  : return _C;                                   \
                        case _AB : return _AB;                                  \
                        default  : return 0;                                    \
                      }
//---------------------------------------------------------------------------
// 根据Token流,分析寻址方式。返回寻址方式的号码。
// 被FindResvInstOPset()调用。
// 假想字串没有语法错误。
// 输入:p 指向Operand结点, 即p->Token == Operand。
// 0=err 1='#' 2='@' ...
//---------------------------------------------------------------------------
int8u MacroAsmber::GetDataType(Tokenfield* p)
{ p = p->ExpPt;         // 现在 p 指向操作数Operand的头

  TriVal* t;  int8u ch;

  OpndExpTypCal(p, t, ch); // 带回t指针,ch。
  //if(err && Pass_2) { return 0; } // endif
  // even have errs... (in pass1) Only to find the length of instruction
   switch( ch )
   { case ' ' : { switch(t->typ)
                  { case LB_REG  : { Only_1_REG } // return has in it
                    case LB_DATA : { return direct; } // end case
                    case LB_NUM  : { return _num;   } // end case
                    case LB_BIT  : { return _bit;   } // end case
                    case LB_CODE : { return _code_; } // end case
                    default      : { return 0; } // error
                  } // end switch
                } // end case

     case '#' : { switch(t->typ)
                  { case LB_DATA : { return _xx_; } // end case
                    case LB_NUM  : { return _xx_; } // end case
                    case LB_CODE : { return _xx_; } // end case
                    case LB_IDATA: { return _xx_; } // end case
                    case LB_XDATA: { return _xx_; } // end case
                    case LB_SEG  : { return _xx_; } // end case
                    case LB_BIT  : { return _xx_; } // end case
                    default      : { return 0; } // error
                  } // end switch
                } // end case

     case '@' : { switch(t->typ)
                  { case LB_REG  : { indirect_REG } // return has in it
                    default      : { return 0; } // error
                  } // end switch
                } // end case

     case '/' : { switch(t->typ)
                  { case LB_BIT  : { return _neg_; } // end case
                    case LB_NUM  : { return _neg_; } // end case
                    default      : { return 0; } // error
                  } // end switch
                } // end case

     default  : { EThrows(printf("\nGetDataType out of run! "); Debugkey;); // debug
                } // end default
   } // end switch
  return 0;    // "Return Error!!!   Zero means error occured."
} // end GetDataType
//---------------------------------------------------------------------------

//---------------------------------------------------------------------------
// pt指向Operand底下的Token链链头。
// 被GetDataType()调用。
// 当 typmode == true 时,表达式只进行类型计算,
// 出现算不出的式子,值为0,类型为num,rel=='A'。
//---------------------------------------------------------------------------
ERR MacroAsmber::OpndExpTypCal(Tokenfield* pt, TriVal const* &t, int8u &ch)
{ switch(pt->Token)
  { case '#': case '@': case '/':
     { ch = (int8u)pt->Token; pt = pt->next; break; } // end case
    default : { ch = ' '; } // end default
  } // end switch

  Assert( if(pt->Token != ExpresnKn)
           { EThrows(printf("\nOpndExpTypCal out of run!"); Debugkey;); // debug
             return Have_Errs;
           } // end else
        );
  pt = pt->ExpPt; // Now, 令pt指向Expr底下的Token链链头。

  // Now, pt 指向expression头.
  ERR err;                      // typmode == true !!
  t = LabMger->CalExpression(err, pt, NULL, true); // 带回err值。
  return err;
} // end OpndExpTypCal
//---------------------------------------------------------------------------


//---------------------------------------------------------------------------
// end MAsmber_C3.cpp
//---------------------------------------------------------------------------
//               Written by JamesyFront.    ZLGmcu Dev.Co.Ltd.  2002.
//---------------------------------------------------------------------------



















⌨️ 快捷键说明

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