📄 masmber_c3.cpp
字号:
{ 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 + -