/// <summary> /// 声明一个局部变量 /// </summary> /// <param name="Size"></param> /// <returns></returns> public Int32 MemoryAlloc(string varName, Int32 Size) { Int32 MemorySize = Size / 4 + Size % 4; OutputObject asnFile = new OutputObject(); asnFile.Asn($";alloc local variable"); for (Int32 Index = 0; Index < MemorySize; Index++) { asnFile.Asn($"mov r0,0"); asnFile.Asn($"str r0,dptr"); asnFile.Asn($"mov r0,1"); asnFile.Asn($"add dptr,dptr,r0"); } if (SymbolMap.ContainsKey(varName)) { throw new Exception($"该作用域内变量重复定义:{varName}"); } SymbolMap.Add(varName, new VarInfo { Offset = 0, Size = MemorySize }); string[] keyArray = SymbolMap.Keys.ToArray(); for (int i = 0; i < keyArray.Length; i++) { SymbolMap[keyArray[i]].Offset += MemorySize; } asnFile.Out(); return(MemorySize); }
/// <summary> /// 变量赋值 /// </summary> /// <param name="varName"></param> /// <param name="Value"></param> public void AssignmentVar(string varName, dynamic Value) { LocalVariable.VarInfo varInfo = LifeCycle.GetVarInfo(varName); byte[] bytes = BitConverter.GetBytes(Value); List <byte> tmpByteList = bytes.ToList(); for (int i = 0; i < 4 - ((bytes.Length % 4 == 0) ? 4 : (bytes.Length % 4)); i++) { tmpByteList.Add(0x00); } bytes = tmpByteList.ToArray(); List <Int32> _Values = new List <Int32>(); for (int i = 0; i < bytes.Length / 4 + bytes.Length % 4; i++) { _Values.Add(BitConverter.ToInt32(bytes, i * 4)); } OutputObject asnFile = new OutputObject(); asnFile.Asn($";set variable value"); for (int i = 0; i < (varInfo.Size > _Values.Count ? _Values.Count : varInfo.Size); i++) { asnFile.Asn($"mov r0,{varInfo.Offset - i}"); asnFile.Asn($"sub r0,dptr,r0"); asnFile.Asn($"mov r1,{_Values[i]}"); asnFile.Asn($"str r1,r0"); } asnFile.Out(); }
/// <summary> /// 释放局部变量 /// </summary> public void MemoryFree() { Int32 StackSize = 0; string[] keyArray = SymbolMap.Keys.ToArray(); for (int i = 0; i < keyArray.Length; i++) { StackSize += SymbolMap[keyArray[i]].Size; } OutputObject asnFile = new OutputObject(); asnFile.Asn($";free all local variable"); asnFile.Asn($"mov r0,{StackSize}"); asnFile.Asn($"sub dptr,dptr,r0"); asnFile.Out(); }
/// <summary> /// 将函数返回值存储到变量varName中 /// </summary> /// <param name="varName"></param> public void ReturnAsignVar(string varName) { LocalVariable.VarInfo varInfo = LifeCycle.GetVarInfo(varName); OutputObject asnFile = new OutputObject(); asnFile.Asn($";set return variable value"); for (int i = 0; i < varInfo.Size; i++) { asnFile.Asn($"mov r0,{varInfo.Offset - i}"); asnFile.Asn($"sub r0,dptr,r0"); asnFile.Asn($"ldr r1,r0"); asnFile.Asn($"mov r0,{i}"); asnFile.Asn($"add r0,dptr,r0"); asnFile.Asn($"str r1,r0"); } }
/// <summary> /// 函数准备编译 /// 定义函数参数入栈规则 /// 1、参数从左往右入栈 /// 2、参数入栈的全部是地址 /// 3、函数准备时对所有参数进行一次拷贝 /// </summary> public void FuncPrepare() { OutputObject asnFile = new OutputObject(); asnFile.Asn($";declare function {FunctionName}"); asnFile.Asn($"section {FunctionName}:"); if (!FunctionName.Equals("main")) { //如果不是主函数,必须保存现场 asnFile.Asn($"push lr"); asnFile.Asn($"push cpsr"); } asnFile.Out(); //按次序实例化参数 Parameters.ForEach(x => { LocalEnvironment.DeclareParam(x.ParamName, x.Size); }); }
/// <summary> /// 变量对变量赋值 /// </summary> /// <param name="destName"></param> /// <param name="srcName"></param> public void VarAsignVar(string destName, string srcName) { LocalVariable.VarInfo destVarInfo = LifeCycle.GetVarInfo(destName); LocalVariable.VarInfo srcVarInfo = LifeCycle.GetVarInfo(srcName); OutputObject asnFile = new OutputObject(); asnFile.Asn($";set variable value"); for (int i = 0; i < destVarInfo.Size; i++) { asnFile.Asn($"mov r0,{srcVarInfo.Offset - i}"); asnFile.Asn($"sub r0,dptr,r0"); asnFile.Asn($"ldr r1,r0"); asnFile.Asn($"mov r0,{destVarInfo.Offset - i}"); asnFile.Asn($"sub r0,dptr,r0"); asnFile.Asn($"str r1,r0"); } asnFile.Out(); }
/// <summary> /// 声明函数参数,不进行压栈,直接对sp进行操作 /// </summary> /// <param name="varName"></param> /// <param name="Size"></param> /// <returns></returns> public Int32 DeclareParam(string varName, Int32 Size) { Int32 MemorySize = Size / 4 + Size % 4; OutputObject asnFile = new OutputObject(); asnFile.Asn($";declare parameter variable"); asnFile.Asn($"mov r0,{MemorySize}"); asnFile.Asn($"add dptr,dptr,r0"); SymbolMap.Add(varName, new VarInfo { Offset = 0, Size = MemorySize }); string[] keyArray = SymbolMap.Keys.ToArray(); for (int i = 0; i < keyArray.Length; i++) { SymbolMap[keyArray[i]].Offset += MemorySize; } asnFile.Out(); return(MemorySize); }
public void FuncReturn(string varName) { OutputObject asnFile = new OutputObject(); //释放数据栈 LocalEnvironment.MemoryFree(); if (FunctionName.Equals("main")) { asnFile.Asn($"end"); } else { List <string> ReturnParam = new List <string>(); ReturnParam.Add(ReturnVariable.ParamName); LocalEnvironment.PrepareParam(ReturnParam); //恢复现场 asnFile.Asn($"pop cpsr"); asnFile.Asn($"pop lr"); asnFile.Asn($"ret"); } asnFile.Out(); }
/// <summary> /// 准备函数参数 /// </summary> /// <param name="varName"></param> /// <param name="Size"></param> public void PrepareParam(List <string> Params) { OutputObject asnFile = new OutputObject(); asnFile.Asn($";prepare parameter variable"); asnFile.Asn($"mov r2,dptr"); Params.ForEach(x => { VarInfo varInfo = GetVarInfo(x); for (int i = 0; i < varInfo.Size; i++) { asnFile.Asn($"mov r0,{varInfo.Offset - i}"); asnFile.Asn($"sub r0,dptr,r0"); asnFile.Asn($"ldr r1,r0"); asnFile.Asn($"str r1,r2"); asnFile.Asn($"mov r0,1"); asnFile.Asn($"add r2,r2,r0"); } }); asnFile.Out(); }