LIFO栈算法设计

3

我正在实现一个基于堆栈的虚拟机,一直在尝试阅读有关处理堆栈算法的文献或概述,但没有发现相关内容。以下是一个示例:

int i = 3
int j = 4
int k = 5

假设ijk是本地变量,因此它们通常存储在堆栈上。汇编/字节码翻译大致如下:

pushi 3
pushi 4
pushi 5

堆栈将是:5 4 3

我有一个整数堆栈和一个字符串堆栈,因此使用了pushi,但我的问题是,如果我想在定义后执行像int x = i + j这样的操作,编译器或解释器如何知道我需要分别弹出两个三个元素,并且要尽力不丢失k(将其保存在寄存器中或其他地方,然后再将其推回)?

希望我的问题有些意义,可能还有更聪明的方法:P谢谢您的任何见解!


你需要将操作符和中间结果都堆叠起来。你正在阅读哪本关于表达式求值和/或编译器设计的书?可以查看https://dev59.com/x3VD5IYBdhLWcg3wXaed。 - anon
目前没有阅读任何书籍。只是通过谷歌和我学校的JSTOR同行评审文章进行研究。感谢您提供的参考,但如果大多数这些书不那么昂贵就好了 =P - David Titarenco
没有阅读书籍,你不会走得太远。但这是一个关于如何编写编译器的好的在线资源 - http://compilers.iecc.com/crenshaw。 - anon
2个回答

2
这通常是通过使用称为 堆栈帧 的东西来完成的。您一次性分配所有本地变量的空间(除了分配/优化到寄存器的变量),存储该块的基地址,并从那里操作偏移量。然后在作用域退出时从堆栈中弹出所有内容。

2
巴赫 - 在速度类型的竞争中,你赢了 :) - Michael Dorgan
很棒,所以在作用域解析期间,编译器会说像变量i在memaddress,变量n在memaddress,因此稍后在该特定堆栈帧中,您可以访问i或n,并且指针只需“转到”那里,而无需弹出或推入任何内容。 - David Titarenco
没错,这也是调试器在堆栈中找到你的东西的方式。 - Nikolai Fetissov

2
在这种情况下,编译器所做的是通过直接添加到堆栈指针来一次性获取一堆堆栈空间,然后使用普通的内存读取函数索引堆栈值,而不使用push和pop。完成后将堆栈减回其原始值。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接