简体   繁体   English

MemoryError:python 中的堆栈溢出

[英]MemoryError: stack overflow in python

This is the code for MIPS Single cycle data path processor.这是 MIPS 单周期数据路径处理器的代码。 It is implementing IDEA algorithm (ASM code).它正在实现 IDEA 算法(ASM 代码)。 I have numerous function calls and the whole architecture runs this assembly IDEA code for 16 times.我有很多函数调用,整个架构运行这个程序集 IDEA 代码 16 次。 I am getting this Stack overflow error.我收到此堆栈溢出错误。 Previously i was getting a Recursion depth error but it got solved using the set.recusionlimit() function.以前我遇到了递归深度错误,但使用 set.recusionlimit() 函数解决了它。 The code seems okay but i dont know why it is giving me a Stack overflow error.代码看起来没问题,但我不知道为什么它给我一个堆栈溢出错误。 Assembly code runs fine in a different assembler.汇编代码在不同的汇编器中运行良好。

MemoryError: stack overflow内存错误:堆栈溢出

#===========================================================
#SingleCycle Datapath Processor running IDEA algorithm asm
#Sukrut Kelkar
#===========================================================

import sys
import os

def main():

    global instrMem
    global dataMem
    global RegisterFile
    global WD3
    global Result
    global A3
    global RD3
    global PC
    global Branch
    global zero
    global Imm
    global RD
    global f
    sys.setrecursionlimit(10000)
    f=0
    RD=0
    Imm=0
    zero=0
    Branch=0
    PC=-1
    Result=0
    WD3=0
    A3=0
    RD3=0

    #Instruction Memory
    instructM=open('instructionOpcodes_v1.txt','r')
    instrMem = dict(enumerate(line.strip() for line in instructM))
    print ('\ninstrMem: ',instrMem)

    #Register files
    RegisterFile = {k:0 for k in range(31)}

    #Data Memory
    dataM=open('keys.txt','r')
    dataMem = dict(enumerate(line.strip() for line in dataM))
    print ('\ndataMem: ',dataMem)

    ProgramCounter()

def ProgramCounter():
    global PC
    PC=mux((Branch & zero),adderPC(PC),Imm)
    A=PC
    instrMemo(A)

#Instrction Memory Module    
def instrMemo(A):
    global Op
    global funct
    global RD
    global A1
    global A2
    global Ard
    global Imm
    global instr

    for i in instrMem:
            if A==i:
                RD=instrMem[i]

    #scale_data= 16 ## equals to hexadecimal
    instr=bin(int(RD, 16))[2:].zfill(32)

    if int(instr,2)==1:
        sys.exit("Its Done!!!")

    Op=int(instr[0:6],2)#opcode
    funct=int(instr[21:27],2)#funct
    rt=instr[11:16]#A2 rt
    rd=instr[16:21]# rd
    rs=instr[6:11]#A1 rs
    Imm=int(instr[16:32],2)#Immediate offset
    #Imm=int(Im,2)
    A1=int(rs,2)
    A2=int(rt,2)
    Ard=int(rd,2)
    ControlU(Op,funct)


#Control Unit Module    
def ControlU(Op,funct):
    global RegWrite
    global RegDst
    global AluSrc
    global Branch
    global MemWrite
    global MemtoReg
    global AluCon
    global ALUresult
    global A3
    #R-type Instructions
    if Op==0:
        RegWrite=1
        RegDst=1
        AluSrc=0
        Branch=0
        MemWrite=0
        MemtoReg=0

        if funct==0:
            AluCon=0
        elif funct==1:
            AluCon=1
        elif funct==2:
            AluCon=2
        elif funct==3:
            AluCon=3
        elif funct==4:
            AluCon=4
        elif funct==5:
            AluCon=5
    #Load Word       
    elif Op==2:
        RegWrite=1
        RegDst=0
        AluSrc=1
        Branch=0
        MemWrite=0
        MemtoReg=1
        AluCon=0
    #Load Imm
    elif Op==1:
        RegWrite=1
        RegDst=0
        AluSrc=1
        Branch=0
        MemWrite=0
        MemtoReg=0
        AluCon=0    
    #Store Word      
    elif Op==3:
        RegWrite=0
        RegDst=0
        AluSrc=1
        Branch=0
        MemWrite=1
        MemtoReg=0
        AluCon=0    
    #Branch if equal
    elif Op==5:
        RegWrite=0
        RegDst=0
        AluSrc=0
        Branch=1
        MemWrite=0
        MemtoReg=0
        AluCon=1
    #Add Imm
    elif Op==9:
        RegWrite=1
        RegDst=0
        AluSrc=1
        Branch=0
        MemWrite=0
        MemtoReg=0
        AluCon=0
    #Branch if zero
    elif Op==4:
        RegWrite=0
        RegDst=0
        AluSrc=0
        Branch=1
        MemWrite=0
        MemtoReg=0
        AluCon=12
    #Branch if greater than
    elif Op==6:
        RegWrite=0
        RegDst=0
        AluSrc=0
        Branch=1
        MemWrite=0
        MemtoReg=0
        AluCon=6    
    #Branch if less than
    elif Op==7:
        RegWrite=0
        RegDst=0
        AluSrc=0
        Branch=1
        MemWrite=0
        MemtoReg=0
        AluCon=7
    #AddMod
    elif Op==11:
        RegWrite=1
        RegDst=1
        AluSrc=0
        Branch=0
        MemWrite=0
        MemtoReg=0
        AluCon=11  
    #MulMod
    elif Op==10:
        RegWrite=1
        RegDst=1
        AluSrc=0
        Branch=0
        MemWrite=0
        MemtoReg=0
        AluCon=10
    A3=mux(RegDst,A2,Ard)
    print ('A3: ',A3)
    RegisterFiles(A1,A2)

#Register File Module
def RegisterFiles(A1,A2):
    global RD1
    global RD2
    global SrcA
    global SrcB
    for i in RegisterFile:
        if (A1==i):
            RD1=RegisterFile[i]

    for i in RegisterFile:
        if (A2==i):
            RD2=RegisterFile[i]

    SrcB=mux(AluSrc,RD2,Imm)
    SrcA=RD1
    ALU_main(AluCon,SrcA,SrcB)


#Arithmetic Logic Unit ALU 
def ALU_main(AluCon,inp1,inp2):
    global ALUresult
    global zero

    if AluCon==0:#add
        ALUresult=inp1+inp2

    elif AluCon==1:#sub
        ALUresult=inp1-inp2

    elif AluCon==2:#mul
        ALUresult=inp1*inp2

    elif AluCon==3:#or
        ALUresult=inp1 | inp2

    elif AluCon==4:#and
        ALUresult=inp1 & inp2

    elif AluCon==5:#XOR
        ALUresult=inp1 ^ inp2

    elif AluCon==11:#AddMod
        ALUresult=inp1+inp2
        while ALUresult>65536:
            ALUresult=ALUresult-65536         

    elif AluCon==10:#MulMod
        if inp1==0:
            inp1=65536

        if inp2==0:
            inp2=65536

        #ALUresult=int(inp1,2)*int(inp2,2)
        ALUresult=inp1*inp2
        if ALUresult==65536:
            ALUresult=0

        while ALUresult>65537:
            ALUresult=ALUresult-65537

    elif AluCon==6:#BGT
        if inp2>inp1:
            ALUresult=0
        else:
            ALUresult=1

    elif AluCon==7:#BLT
        if inp2<inp1:
            ALUresult=0
        else:
            ALUresult=1

    elif AluCon==12:#BZ
        if inp1==inp2:
            ALUresult=0
        else:
            ALUresult=1

    if ALUresult==0:
        zero=1
    else:
        zero=0
    dataMemo()

#Write      
def RegisterFileWrite():    
    global WD3
    Result=mux(MemtoReg,ALUresult,RD3)
    WD3=Result
    if RegWrite==1:
        for i in RegisterFile:
            if (A3==i):
                RegisterFile[i]=WD3

    final()


def dataMemo():
    global RD3
    global Result
    WD=RD2
    A4=ALUresult

    if MemWrite==0:
        for i in dataMem:
            if A4==i:
                RD3=int(dataMem[i],16)
    else:
        for i in dataMem:
            if A4==i:
                dataMem[i]=hex(WD)[2:]
        os.system('cls')

    RegisterFileWrite()


def mux(sel,firstinp,secondinp):
    if sel==0:
        out=firstinp
    else:
        out=secondinp
    return(out)


def adderPC(inp):
    addOut=inp+1
    return(addOut)  

def final():
    global f
    f+=1
    print (f)
    print ('\nPC: ',PC)
    #if RegisterFile[24]>4:
    print ('dataMem: ',dataMem)
        #j=112
        #while j<175:
    if RegisterFile[24]==4:
        print ('Instruction: ',instr)
        print ('Op: ',Op)
        print ('Funct: ',funct)
        print ('Imm: ',Imm)
        print ('SrcA: ',SrcA)
        print ('SrcB: ',SrcB)
        print ('ALUresult: ',ALUresult)
        print ('zero: ',zero)
        print ('RegisterFile: ',RegisterFile)
        print(sys.getrecursionlimit())
        #sys.exit("count is 4")
         #   final=dataMem[j]+dataMem[j+1]
          #  j=j+1
        #print ('\nEncrypted Data: ',final)

    ProgramCounter()


if __name__ == '__main__':
    main()

You are getting the stackoverflow because you set the recursion limit too high.由于您将递归限制设置得太高,您正在获得计算器溢出。 You can't set it as high as you like 你不能把它设置得像你喜欢的那样高

sys.setrecursionlimit(limit) Set the maximum depth of the Python interpreter stack to limit. sys.setrecursionlimit(limit)将 Python 解释器堆栈的最大深度设置为 limit。 This limit prevents infinite recursion from causing an overflow of the C stack and crashing Python.此限制可防止无限递归导致 C 堆栈溢出和 Python 崩溃。

The highest possible limit is platform-dependent.可能的最高限制取决于平台。 A user may need to set the limit higher when they have a program that requires deep recursion and a platform that supports a higher limit.当用户有需要深度递归的程序和支持更高限制的平台时,他们可能需要将限制设置得更高。 This should be done with care, because a too-high limit can lead to a crash.这应该小心完成,因为过高的限制会导致崩溃。

If the new limit is too low at the current recursion depth, a RecursionError exception is raised.如果当前递归深度的新限制太低,则会引发 RecursionError 异常。

Changed in version 3.5.1: A RecursionError exception is now raised if the new limit is too low at the current recursion depth.在 3.5.1 版更改:如果新限制在当前递归深度下太低,现在会引发 RecursionError 异常。

Your real problem was that you are hitting the recursion limit.你真正的问题是你达到了递归限制。 Why didn't you just post that traceback?你为什么不直接发布那个追溯?

You appear to be using function calls like goto.您似乎正在使用像 goto 这样的函数调用。 Python doesn't do tail call optimisation so this technique won't work. Python 不进行尾调用优化,因此该技术不起作用。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM