PVM中的主要数据结构是";Regular";堆栈(类似于受限的列表PUSH=APPEND,POP=POP)。堆栈的主要操作是加载/推送和存储/弹出。我们在向上增长的堆栈顶部加载/压入一个值(递增STACKP-STACK指针-它索引顶部);我们从堆栈顶部存储/弹出一个值(递减STACKP)。有一个次要的块堆栈,用于存储有关嵌套循环、TRY和WITH语句的信息。(=。例如,中断状态转换为使用块堆栈来确定要中断哪个循环的代码(以及如何在TheLoop外的第一个语句继续执行)。当循环、TRY/EXCEPT和WITH语句启动时,关于它们的块的信息被推送到块堆栈上;当它们终止时,该信息从Bock堆栈中弹出。对于今天的演讲来说,块堆栈太复杂了,不需要理解它:因此,当我们运行跨块堆栈指令时,我们会指出我们忽略了它们的事实。下面是一个执行计算d=a+b*c的简单堆栈操作序列的示例,假设a、b、c和d是函数中的局部变量:假设co_varames是(';a';,';b';,。),并且这些名称的实际值存储在并行的元组(1,2,3,NONE)中:例如,';a';的值是1,';b';的值是2,';c';的值是3,而';d';的值是NONE。正如我们将在LOAD_FAST N的含义下面更详细地看到的那样,存储在co_varnames[N]中的值存储在co_varnames[N]中,写入stackp+=1,stackp[stackp]=co_varnames[N]store_fast N存储/弹出堆栈顶部的值到co_varnames[N]中,写入的co_varnames[N]=STACK[N]。AND STACKP-=1 BINARY_MAXPLY加载/将顶部的两个值的*推入堆栈,写入的堆栈[STACKP-1]=STACKP[STACKP-1]*STACKP[STACKP];STACKP-=1(将堆栈顶部的两个值转换为它们的乘积)BINARY_ADD LOAD/PUSH将顶部写入的堆栈上的两个值的+加载/推入堆栈[STACKP-1]=STACKP[STACKP-1]+STACKP[STACKP];STACKP-=1(将堆栈顶部的两个值转换为它们的和)d=a+b*c的PVM代码为LOAD_FAST 0 LOAD_FAST 1 LOAD_FAST 2 BINARY_MULPLY BINARY_ADD_STORE_。+-+3||+-+2||+-+1||+-+0||+。意思是空栈)执行LOAD_FAST 0.。+-+3||+-+2||+-+1||+-+0|1:a|++。-+STACK(STACKP=0)执行LOAD_FAST 1.。+-+3||+-+2||+-+1|2:b|+-+0|1:a|++。-+STACKP=1的STACK(WITH STACKP=1)执行LOAD_FAST 2.。+-+3|+-+2|3:c|++-+1|2:b|++-+0|1:a|++。-+STACKP=2的STACK(WITH STACKP=2)执行BINARY_MULPLY.。+-+3||+-+2||+-+1|6:b*c|+-+0|1:a|++。-+STACKP=1的STACK(WITH STACKP=1)执行BINARY_ADD.。+-+3||+-+2||+-+1||+-+0|7:a+b*c|+。-+STACK(STACKP=0)执行STORE_FAST 3.。+-+3||+-+2||+-+1||+-+0||+。-+堆栈(堆栈=-1)在该点d';的值为7,即执行STORE_FAST时位于堆栈顶部的值。这些名称的实际值存储在四元组(1,2,3,7).问题:显示(通过绘制我上面绘制的)以下指令COMPUTE d=(a+b)*c LOAD_FAST 0 LOAD_FAST 1 BINARY_ADD LOAD_FAST 2 BINARY_MULPLY STORE_FAST 3任何表达式都可以转换为类似的代码,供PVM评估其值。-PVMEach指令的控制(获取/执行周期)。第一个字节是操作或字节码;后两个字节是该字节码的操作数(但并非所有字节码都需要操作数:LOAD_FAST需要;BINARY_ADD不需要)。两个字节(16位)可以表示数字0到65,536:因此,Python函数可能不会有超过65,536个不同的局部变量名称。存储指令