📄 tcwiz2.cpp
字号:
CompOperators[inst.Instr - JA]);
//if (i) sprintf(EndOf(LineBuffer),"(unsigned)");
CompareVar.EndAddress = inst.Data11;
GetLabel(inst.Data11,tmp);
sprintf(EndOf(LineBuffer),"(%s))",(char *)CompareVar.Operand2);
Byte far *p=Inst+InstLen;
// If we are just checking the registers modified in this
// part of the code, don't decode ternary operators etc.
if (!RegUsed && !RegModified)
// else, Check for ternary operator code here.
p = CheckForTernaryOperCode(Inst+InstLen,LineBuffer+2);
if(p!=Inst+InstLen)
{
ctr += p-Inst;
Inst = p;
// Just to fool the incrementing code at the end of the proc.
InstLen=0;
}
else
{
sprintf(EndOf(LineBuffer)," goto %s;",(char *)tmp);
CheckAndOutput(LineBuffer,How,sList);
}
((char *)CompareVar.Operand1)[0]=0; // reset.
break;
case SHL : case SHR :
if (inst.Operand2==IMMEDIATE)
tmp1 += inst.Data21;
else if (inst.Operand2==REG_DIRECT)
tmp1 += GetReg(inst.Data21);
else assert(0);
case INC : case DEC :
switch(inst.Operand1)
{
case REG_DIRECT :
// If the register used is not a register variable...
if (!RegisterVariable(inst.Data11))
{
char *t;
switch(inst.Instr)
{
case INC : t="+1"; break;
case DEC : t="-1"; break;
case SHL : t="<<"; break;
case SHR : t=">>"; break;
}
Regs[inst.Data11] = toString("(") + \
GetReg(inst.Data11) + t + tmp1 + ")";
SetRegModified(inst.Data11);
SetRegUsed(inst.Data11);
break;
}
// If it is a register variable, or other operands,...
default :
tmp=GetOperand1(inst);
char *t;
switch(inst.Instr)
{
case INC : t="++"; break;
case DEC : t="--"; break;
case SHL : t="<<="; break;
case SHR : t=">>="; break;
}
sprintf(LineBuffer,"%s%s%s;",(char *)tmp,\
t,(char *)tmp1);
CheckAndOutput(LineBuffer,How,sList);
break;
}
break;
case ADC : case SBB :
// only the high words of the long-int are involved in
// ADC & SBB. Hence subtract 2 from the variable to get
// the actual address of the long int.
int whichOper;
whichOper=(inst.Operand1!=REG_DIRECT)?1:2;
if (whichOper==1) inst.GetVariable(v1,1);
else inst.GetVariable(v1,2);
DelVar(v1-2); DelVar(v1);
AddVar(v1-2,VAR_LONG,4);
if (inst.Instr==ADC) inst.Instr=ADD;
else inst.Instr=SUB;
goto ComForMovingData;
// We get an 'LES' instruction while using 'far' pointers.
// eg. LES BX,[1000] means we are loading es:bx with far-pointer
// located at 1000. Here, I just ignore the 'es' part of the
// instruction, and load BX with [1000].
case LES : inst.Instr=MOV;
case MOV : case ADD : case SUB :
case AND : case OR : case XOR :
// Check if the destination operand is a part of a long-int.
// Execute the instruction only if it is the HIWORD of the
// long-int.
ComForMovingData:
int Use2ndData=0;
int HiWordPrefix=0;
whichOper=(inst.Operand1!=REG_DIRECT)?1:2;
if (whichOper==1) inst.GetVariable(v1,1);
else inst.GetVariable(v1,2);
if (IsLongInt(v1))
{
// If it is not the 1st word of the long-int, ignore
// the instruction.
if (!IsFirstWordOfLongInt(v1))
{
if (inst.Operand2==IMMEDIATE)
{
PrevImmValueStored=1;
PrevImmediateValue=inst.Data21;
}
if (whichOper==2)
{
inst.SetVariable(v1-2,2);
HiWordPrefix=1;
}
else break;
}
if (inst.Operand2==IMMEDIATE)
{
// This instruction operates on the 1st word using
// an immediate value. Grab the 2nd word of the
// immediate value - which could be the previous or
// next instruction.
// If it has not been obtained from previous
// instruction it must be in the next instruction.
if (!PrevImmValueStored)
{
Inst+=InstLen;
d.TraceInst(Inst,InstLen);
if (d.CurInst.Instr==ADC) d.CurInst.Instr=ADD;
if (d.CurInst.Instr==SBB) d.CurInst.Instr=SUB;
if(d.CurInst.Instr!=inst.Instr ||
d.CurInst.Operand2!=IMMEDIATE)
{
sprintf(errorStr,"Error understanding long int code at %X",InstAddr);
ErrorList.Add(errorStr);
break;
}
PrevImmediateValue=d.CurInst.Data21;
}
inst.Data22=inst.Data21;
inst.Data21=PrevImmediateValue;
PrevImmValueStored=0;
Use2ndData=1;
}
}
switch(inst.Operand1)
{
case REG_INDIRECT :
case INDEXED_BYTE :
case INDEXED_WORD :
tmp=GetOperand1(inst);
goto PrintVariableAssignment;
case MEMORY :
tmp=GetOperand1(inst);
PrintVariableAssignment:
tmp1=tmp;
sprintf(LineBuffer,"%s %s= ",(char *)tmp,\
ArithOperators[inst.Instr - MOV]);
switch(inst.Operand2)
{
case IMMEDIATE :
s_LineBuffer += (Word)inst.Data21;
if (Use2ndData) // See above.
s_LineBuffer += (Word)inst.Data22;
break;
case REG_DIRECT :
CheckAndSetRegUsed(inst.Operand2,inst.Data21);
tmp=GetOperand2(inst);
strcat(LineBuffer,(char *)tmp);
// Is it a long-int?
if (strncmp((char *)tmp,"HIWORD",6)==0)
Use2ndData=1; // Used in the checking below.
// If it is like MOV addr,REG then do a false
// assignment MOV REG,addr so that any
// following instructions of the format
// MOV addr,REG are translated properly.
if (!RegisterVariable(inst.Data21))
{
tmp=GetOperand1(inst);
Regs[inst.Data21] = tmp;
}
break;
default :
tmp = GetOperand2(inst);
strcat(LineBuffer,(char *)tmp);
break;
}
sprintf(EndOf(LineBuffer),";");
CheckAndOutput(LineBuffer,How,sList);
// check for long-ints and register them
if (Use2ndData)
{
inst.GetVariable(v1,1);
if (!IsLongInt(v1))
{
DelVar(v1-2); DelVar(v1);
AddVar(v1-2,VAR_LONG,4);
}
}
break;
case REG_DIRECT :
tmp=GetOperand2(inst);
tmp1=tmp;
if (HiWordPrefix) tmp=toString("HIWORD(")+tmp+")";
SetRegModified(inst.Data11);
CheckAndSetRegUsed(inst.Operand2,inst.Data21);
// Is it ADD SP,Imm?
if ((inst.Instr == ADD) && \
(inst.Operand2 == IMMEDIATE) && \
(inst.Data11 == Register(1,4)))
{
int dec = (int)inst.Data21 / sizeof(Word);
for(i=0;i<dec;i++,StackTop--)
Stack[StackTop-1] = "";
assert(StackTop>=0); // Stack Underflow?
break;
}
if (inst.Instr == MOV)
Regs[inst.Data11] = tmp;
else
{
tmp = toString("(") + tmp + ")";
Regs[inst.Data11] = GetReg(inst.Data11) + \
" " + ArithOperators[inst.Instr - MOV] \
+ " " + tmp;
}
// Check if it is a register variable
// If so, print it out the same way a memory
// variable is assigned.
if (RegisterVariable(inst.Data11))
{
tmp=GetRegVarName(inst.Data11);
goto PrintVariableAssignment;
}
SetRegModified(inst.Data11);
break;
}
break;
case PUSH : i = StackTop; assert(StackTop<NUM_STACK_LINES);
CheckAndSetRegUsed(inst.Operand1,inst.Data11);
tmp=GetOperand1(inst);
Stack[i] += tmp;
UseAsFnParms[i]=1;
// Check for PUSHs involving part of long-ints.
inst.GetVariable(v1,1);
if (IsLongInt(v1))
UseAsFnParms[i]=IsFirstWordOfLongInt(v1);
// If it is a comma-expression, close the braces.
if (!IsEqualClosingParentheses(Stack[i])) Stack[i] += ")";
// Clear the current stack string to blank.
StackTop++;
Stack[StackTop] = "";
TracingFunctionCall=1;
break;
case POP : if (StackTop<=0)
{
sprintf(errorStr,"Procedure Stack Underflow at %X",InstAddr);
ErrorList.Add(errorStr);
break;
}
StackTop--;
switch(inst.Operand1)
{
case MEMORY :
case INDEXED_BYTE :
case INDEXED_WORD :
tmp = GetOperand1(inst);
sprintf(EndOf(LineBuffer),"%s = %s;",(char *)tmp,\
(char *)Stack[StackTop]);
CheckAndOutput(LineBuffer,How,sList);
break;
case REG_DIRECT :
Regs[inst.Data11] = Stack[StackTop];
SetRegModified(inst.Data11);
break;
}
Stack[StackTop] = "";
TracingFunctionCall=0;
break;
case CALL : TracingFunctionCall=0;
if (IsInternalLongIntProc(inst))
break;
inst.GetVariable(v1,1);
vName=GlobalVars.GetName(v1,VAR_LIB_FUNCTION);
if (!vName) vName=GlobalVars.GetName(v1,VAR_USER_FUNCTION);
if (vName) tmp=vName;
else
{
if (inst.operSize1) tmp = String((Word)inst.Data12);
else tmp="";
tmp += String(inst.Data11);
}
sprintf(EndOf(LineBuffer),"%s(",(char *)tmp);
// For some library procedures, no parameters are passed
// by stack, hence ignore the stack in such cases. This
// is checked by finding if the previous instruction
// was a PUSH - if not, just ignore the stack.
if (previnst.Instr==PUSH && StackTop)
{
for(i=StackTop-1;i>=0;i--) if (UseAsFnParms[i]) break;
if (i>=0)
{
sprintf(EndOf(LineBuffer),"%s",(char *)Stack[i]);
i--;
for(;i>=0;i--)
if (UseAsFnParms[i])
sprintf(EndOf(LineBuffer),",%s",(char *)Stack[i]);
}
}
// Append the address of the instruction 'CALL Proc' to
// the pending line buffer, so that this address tag can
// be used to locate this statement in case it has to be
// deleted from the pending lines array.
// Don't terminate LineBuffer with a ';' because pending
// lines should not be terminated now, only while printing.
sprintf(EndOf(LineBuffer),")");
tmp = toString(";") + String((int)InstAddr) + ";";
Regs[REG_AL] = tmp + LineBuffer;
Regs[REG_AX] = tmp + LineBuffer;
Regs[REG_DX] = tmp + toString("HIWORD(") + LineBuffer + ")";
SetRegModified2(REG_AL);
SetRegModified2(REG_AX);
SetRegModified2(REG_DX);
String tmp1 = tmp + LineBuffer;
strcpy(LineBuffer,(char *)tmp1);
CheckAndAddPending(LineBuffer);
// Some functions give a RET/RETF xxxx while returning
// so that there is no need to do a stack unwind by the
// caller. Check for such conditions, and unwind the
// stack by a suitable amount.
Word seg,off;
if (inst.operSize1==1) { seg=inst.Data11; off=inst.Data12; }
else { seg=FP_SEG(Inst); off=inst.Data11; }
Byte far *ProcBegin = (Byte far *)MK_FP(seg,off);
Byte far *ProcEnd = ProcBegin+GetProcSize(ProcBegin);
Disasm d;
d.TraceInst(ProcEnd,i);
int dec = (int)d.CurInst.Data11 / sizeof(Word);
for(i=0;i<dec;i++,StackTop--)
Stack[StackTop-1] = "";
assert(StackTop>=0); // Stack Underflow?
break;
case LOOP : break;
default : sprintf(errorStr,"Unknown Instruction at address %X",InstAddr);
ErrorList.Add(errorStr);
break;
}
Inst += InstLen;
ctr += InstLen;
previnst=inst;
}
CheckAndOutput(NULL,How,sList);
InstAddr = FP_OFF(Inst);
if (GetLabel(InstAddr,tmp))
{
tmp += ":";
CheckAndOutput(tmp,How,sList);
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -