public void FuncEnd(ARGU argu,int ParaNum)
	{//函数结束,恢复所有的寄存器
		Proc currProc = (Proc)argu;
		Vector<String> Registers= currProc.TakenRegs();
		if(ParaNum-4>0)
		//如果参数数目大于4,因为大于4的参数在栈里面,所以恢复寄存器的时候要从f1-3开始往下恢复,f1代表参数数目
		  for(int i=ParaNum-4,j=0;i<ParaNum-4+Registers.size();i++,j++)
		   OutPut.con(" ALOAD " +  Registers.get(j) + " SPILLEDARG " + i + "\n");
		else//如果参数数目小于等于4,因为没有参数在栈里面,所以恢复寄存器的时候从0开始往下恢复即可
		  for(int i=0,j=0;i<Registers.size();i++,j++)
			OutPut.con(" ALOAD " +  Registers.get(j) + " SPILLEDARG " + i + "\n");	
		  OutPut.con("END\n");
	}
	/*public void visit(Call n, ARGU argu)////////////////////
	{
		int size = n.f3.size();
		int i;
		Proc currProc = (Proc)argu;
		Iterator<Node> Itr = n.f3.nodes.iterator();
		    if(currProc.ParaNum>4)//在call语句之后要恢复a0-a3,如果这个函数的参数数目大于4,那么(参数数目-4+使用的寄存器数目)->(参数数目+使用的寄存器数目+ParaStack)为存放a0->a3的栈单元
			 for(int k=0;k<currProc.ParaStack.size();k++)
			  OutPut.con(" ASTORE  "  + " SPILLEDARG "+(currProc.ParaNum-4+currProc.TakenRegs().size()+k)+" "+ currProc.ParaStack.get(k)+ "\n");
			else //如果这个函数的参数数目小于等于4,那么(使用的寄存器数目)->(使用的寄存器数目+ParaStack)为存放a0->a3的栈单元
			 for(int k=0;k<currProc.ParaStack.size();k++)
			  OutPut.con(" ASTORE  "  + " SPILLEDARG "+(currProc.TakenRegs().size()+k)+" "+ currProc.ParaStack.get(k)+ "\n");
		    
		    for(i=0;i<4&&i<size;i++)
		    {//将参数放在a0-a3里
		    	String t1 = ReadTemp((Temp)Itr.next(), argu, 0);
		    	if (t1.charAt(0)=='a')
		    	{
		    		String s =""+t1.charAt(1);
                    if(currProc.ParaNum>4)
			    	 OutPut.con("ALOAD v0 SPILLEDARG "+(currProc.ParaNum-4+currProc.TakenRegs().size()+ Integer.parseInt(s))+"\n");
                    else 
                     OutPut.con("ALOAD v0 SPILLEDARG "+(currProc.TakenRegs().size()+ Integer.parseInt(s))+"\n");
		    		OutPut.con("MOVE "+"a" +i+" v0\n");
		    	}
		    	else
		    	{
			    	OutPut.con(" MOVE " + "a" + i + " "+t1+"\n");
		    	}
		    }
		int j=1;
		for(;i<size;i++,j++)
		{//如果参数多于4个,都将其放到栈里
			String t1 = ReadTemp((Temp)Itr.next(),argu, 0);
			OutPut.con(" PASSARG " + j + " " + t1 +  "\n");
		}
		String t1 = SimpleExpCode(n.f1, argu,0);
		OutPut.con(" CALL " + t1 + "\n");
		if(currProc.ParaNum>4)//在call语句之后要恢复a0-a3,如果这个函数的参数数目大于4,那么(参数数目-4+使用的寄存器数目)->(参数数目+使用的寄存器数目+ParaStack)为存放a0->a3的栈单元
		 for(int k=0;k<currProc.ParaStack.size();k++)
		  OutPut.con(" ALOAD " + currProc.ParaStack.get(k) + " SPILLEDARG "+(currProc.ParaNum-4+currProc.TakenRegs().size()+k)+ "\n");
		else //如果这个函数的参数数目小于等于4,那么(使用的寄存器数目)->(使用的寄存器数目+ParaStack)为存放a0->a3的栈单元
		 for(int k=0;k<currProc.ParaStack.size();k++)
		  OutPut.con(" ALOAD " + currProc.ParaStack.get(k) + " SPILLEDARG "+(currProc.TakenRegs().size()+k)+ "\n");
		}*/
	public void visit(Call n, ARGU argu)////////////////////
	{
		int size = n.f3.size();
		int i;
		Proc currProc = (Proc)argu;
		Iterator<Node> Itr = n.f3.nodes.iterator();
		    if(currProc.ParaNum>4)//在call语句之后要恢复a0-a3,如果这个函数的参数数目大于4,那么(参数数目-4+使用的寄存器数目)->(参数数目+使用的寄存器数目+ParaStack)为存放a0->a3的栈单元
			 for(int k=0;k<currProc.ParaStack.size();k++)
			  OutPut.con(" ASTORE  "  + " SPILLEDARG "+(currProc.ParaNum-4+currProc.TakenRegs().size()+k)+" "+ currProc.ParaStack.get(k)+ "\n");
			else //如果这个函数的参数数目小于等于4,那么(使用的寄存器数目)->(使用的寄存器数目+ParaStack)为存放a0->a3的栈单元
			 for(int k=0;k<currProc.ParaStack.size();k++)
			  OutPut.con(" ASTORE  "  + " SPILLEDARG "+(currProc.TakenRegs().size()+k)+" "+ currProc.ParaStack.get(k)+ "\n");
		    
		    for(i=0;i<4&&i<size;i++)
		    {//将参数放在a0-a3里
		    	String t1 = ReadTemp((Temp)Itr.next(), argu, 0);
		    	if (t1.charAt(0)=='a')
		    	{
		    		String s =""+t1.charAt(1);
                    if(currProc.ParaNum>4)
			    	 OutPut.con("ALOAD v0 SPILLEDARG "+(currProc.ParaNum-4+currProc.TakenRegs().size()+ Integer.parseInt(s))+"\n");
                    else 
                     OutPut.con("ALOAD v0 SPILLEDARG "+(currProc.TakenRegs().size()+ Integer.parseInt(s))+"\n");
		    		OutPut.con("MOVE "+"a" +i+" v0\n");
		    	}
		    	else
		    	{
			    	OutPut.con(" MOVE " + "a" + i + " "+t1+"\n");
		    	}
		    }
		int j=1;
		for(;i<size;i++,j++)
		{//如果参数多于4个,都将其放到栈里
	    	String t1 = ReadTemp((Temp)Itr.next(), argu, 0);
	    	if (t1.charAt(0)=='a')
	    	{
	    		String s =""+t1.charAt(1);
                OutPut.con("ALOAD v0 SPILLEDARG "+(currProc.ParaNum-4+currProc.TakenRegs().size()+ Integer.parseInt(s))+"\n");
    			OutPut.con(" PASSARG " + j + " v0 \n");
	    	}
	    	else
	    	{
				OutPut.con(" PASSARG " + j + " " + t1 +  "\n");
	    	}
		//	String t1 = ReadTemp((Temp)Itr.next(),argu, 0);
		//	OutPut.con(" PASSARG " + j + " " + t1 +  "\n");
		}
		String t1 = SimpleExpCode(n.f1, argu,0);
		OutPut.con(" CALL " + t1 + "\n");
		if(currProc.ParaNum>4)//在call语句之后要恢复a0-a3,如果这个函数的参数数目大于4,那么(参数数目-4+使用的寄存器数目)->(参数数目+使用的寄存器数目+ParaStack)为存放a0->a3的栈单元
		 for(int k=0;k<currProc.ParaStack.size();k++)
		  OutPut.con(" ALOAD " + currProc.ParaStack.get(k) + " SPILLEDARG "+(currProc.ParaNum-4+currProc.TakenRegs().size()+k)+ "\n");
		else //如果这个函数的参数数目小于等于4,那么(使用的寄存器数目)->(使用的寄存器数目+ParaStack)为存放a0->a3的栈单元
		 for(int k=0;k<currProc.ParaStack.size();k++)
		  OutPut.con(" ALOAD " + currProc.ParaStack.get(k) + " SPILLEDARG "+(currProc.TakenRegs().size()+k)+ "\n");
		}
	public void FuncBegin(String funcName,ARGU argu,int ParaNum, int MaxStack, int MaxPara)
	{//函数开始,保存所有的寄存器
		Proc currProc = (Proc)argu;
		Vector<String> Registers= currProc.TakenRegs();
		OutPut.con(funcName + " [ " + ParaNum + " ] [ " + MaxStack + " ] [ " +MaxPara+ " ]\n");
		for(int i=4;i<ParaNum;i++)
	      currProc.StackRecorder.add(i);//放父函数传进来的参数
		if(ParaNum-4>0)//如果参数数目大于4,因为大于4的参数都要放到栈里面,所以存放寄存器的栈要接着存放参数的栈单元即为f1-3的位置往下增长,这里f1代表参数数目
		{
		 int i,j;
		 for(i=ParaNum-4,j=0;i<ParaNum-4+Registers.size();i++,j++)
		 {
		   OutPut.con(" ASTORE " + " SPILLEDARG " + i + " " + Registers.get(j) + "\n");
		   currProc.StackRecorder.add(-1);
		 }//存放所有使用的寄存器但除了a0-a3,因为不是temp溢出,所以不用存放temp号,这里用-1代替temp号
		 for(j=0;j<currProc.ParaStack.size();j++,i++)
		 {
		   OutPut.con(" ASTORE " + " SPILLEDARG " + i + " " + currProc.ParaStack.get(j) + "\n");
		   currProc.StackRecorder.add(-1);
		 }//存放a0->a3,因为不是temp溢出,所以不用存放temp号,这里用-1代替temp号
		}
		else
		{
			int i,j; 
		   for(i=0,j=0;i<Registers.size();i++,j++)
		  {
		    OutPut.con(" ASTORE " + " SPILLEDARG " + i + " " + Registers.get(j) + "\n");	
		    currProc.StackRecorder.add(-1);
		  }//如果参数数目小于等于4,因为参数都不放到栈里面,所以存放寄存器的栈从0开始增长即可
		  for(j=0;j<currProc.ParaStack.size();j++,i++)
		  {
			OutPut.con(" ASTORE " + " SPILLEDARG " + i + " " + currProc.ParaStack.get(j) + "\n");
		    currProc.StackRecorder.add(-1);
		  }//存放a0->a3,因为不是temp溢出,所以不用存放temp号,这里用-1代替temp号
		}
	}