如果您无法下载资料,请参考说明:
1、部分资料下载需要金币,请确保您的账户上有足够的金币
2、已购买过的文档,再次下载不重复扣费
3、资料包下载后请先用软件解压,在使用对应软件打开
第六章活动记录ActivationRecordsStack:一个有序的积累或堆积。几乎所有的现代程序设计语言中,函数都可以有局部变量(localvariables),这些局部变量是在函数的入口创建的。在同一时刻可能存在对函数的多个调用(invocations),每个调用都有它自己的局部变量实例(instantiations)。f的每次调用都会创建x的一个新实例,因为存在递归调用,因此可以同时存在x的很多个实例。类似地,每当进入f的函数体时,都将创建一个y的新实例。在很多语言中(例如C、Pascal和Tiger),当函数返回时,局部于该函数的变量便都会消失,因为一个函数只有在它调用的所有函数都返回以后,它才能返回。函数调用是按后进先出(LIFO)方式进行的,如果在函数的入口创建局部变量,在函数的出口删除它们,则可使用“栈”来存放它们。6.1StackFrames6.1StackFrames6.1StackFrames设函数g(…)调用函数f(a1,a2,…an):g是调用者(caller);f是被调用者(callee)。在进入函数f时,栈指针(StackPointer)指向g传递给f的第一个参数。在f的入口,f简单地使SP减去帧的长度而分配一个新栈帧。原来的SP则变成了当前的帧指针(FramePointer)。某些栈帧布局中:FP是一个单独的寄存器;原来的FP保存在存储器中(栈帧内)。当函数f退出时,需要复制FP到SP,并取回保存在存储器中的FP。适合于栈帧大小可变或不连续的情况。如果栈帧的大小是固定不变的,则对于每一个函数f,FP与SP所指的位置总是相差一个已知的常数:“虚”寄存器FP=SP+栈帧大小。问题:当栈帧大小是常数时,为何还讨论帧指针栈帧的大小要到编译处理相当晚的时候才能知道,即要到给临时变量分配的空间大小和用于保护寄存器的空间大小都已确定时。但是,尽早知道形参与局部变量的位移量是有好处的。将局部变量、表达式的中间结果和其他值保存在寄存器中,而不是放在栈帧中,将有助于编译生成的程序快速地运行。算术指令可以直接访问寄存器。在大多数计算机中,存储器的访问需要使用独立的存取指令(loadandstoreinstructions)。即使在那种算术指令可以访问存储器的计算机中,访问寄存器的速度也比访问存储器快。假设函数f在用寄存器r保存了它的一个局部变量的同时调用过程g,而过程g也需用r完成自己的计算:在g使用r之前先将r保护起来(将它保存在栈帧内);完成计算而不再需要时将r恢复(从帧栈中取回被保存的内容)。保护和恢复该寄存器的责任:如果由调用者f来保护和恢复,则称r为调用者保护的(caller-save)寄存器;如果由被调用者g来保护和恢复,则称r为被调用者保护的(callee-save)寄存器;在多数计算机体系结构中,调用者保护的寄存器和被调用者保护的寄存器的概念并不是由硬件来实现的,而是在机器参考手册(machine’sreferencemanual)中规定的。例如MIPS计算机:保留寄存器r16-r23用于跨过程调用(属于被调用者保护的寄存器);其他所有寄存器则不保留用于跨过程调用(属于调用者保护的寄存器)。保护和恢复寄存器的特殊情况:如果f知道某个变量x的值在函数调用以后将不再需要,它可以把x放在一个调用者保护的寄存器中,并且在调用过程g时不保护它。如果f有一个局部变量i,并且在若干次函数调用之前和之后都需使用,则可以把i放在某个被调用者保护的寄存器ri中,并且只在f的入口保护ri一次,在f的出口将ri取回一次。这样,明智地为局部变量和临时变量选择调用者或被调用者保护的寄存器,便可以减少程序执行存储操作的次数。现代计算机中的参数传递约定:一个函数的前k个参数(典型地,k=4或k=6)放在寄存器rp,…rp+k-1中传递,剩余的参数则放在存储器中传递。问题1:原本假定通过将参数传递在寄存器中可以避免的存储器访问,怎样使用寄存器节省时间呢?某些过程并不调用其他的过程——leafprocedure(叶过程),叶过程不必将传入的参数保存到存储器中,常可以不为它们分配栈帧,这是一种重要的节省。有些优化编译器使用过程间寄存器分配(interproceduralregisterallocation),可以一次分析整个程序中的所有函数。这样编译器便可以给不同的过程指派不同的寄存器用于接收参数和存放局部变量。问题1:原本假定通过将参数传递在寄存器中可以避免的存储器访问,怎样使用寄存器节省时间呢?即使f不是叶过程,它仍有可能在调函数h之前完成所有需要使用参数x的操作,于是f可以重写r1,而不需保护它。某些体系结构有寄存器窗口,它们使得每次函数调用都分配一组新的寄存器,而无需存