我有一个英特尔程序集。我需要写一个使用2个堆栈的计算器。例如,我有一个类似23 + 4/2 ^ 4 $的表达式。因此$表示表达式的结束。我要做的是有两个堆栈,一个用于数字,一个用于运算符,并根据运算符优先级推送和弹出它们。
我需要的是如何同时使用2个堆栈用于两个不同的目的。只要我知道esp寄存器指示堆栈中的变量弹出最后一个或推送新变量的位置。但如果我只有一个esp寄存器,我怎么能有两个堆栈?
提前致谢...
答案 0 :(得分:4)
我认为你所寻找的是Dijkstra的分流算法。
我在解释过程中没有使用堆栈就解决了这个问题,只是在执行期间in my blog.
至于制作额外的堆栈,这很容易。所有堆栈,实际上只是一个内存区域,指向顶部和底部。每次推动时,都会递增顶部指针,每次弹出时递减顶部指针。
答案 1 :(得分:2)
或者,你可以用最简单的方式做到这一点,可能会工作,并在内存中实现你的执行堆栈;如上所述,你只需要一个TOP指针和一些算术。
答案 2 :(得分:1)
所有这些答案都假设没有运算符优先级这样的东西。显然,问题中提到的堆栈的使用暗示了与使用运算符优先级的计算有关的正确答案。
这是一个链接,解释了您要实现的目标。 http://epaperpress.com/oper/index.html
答案 3 :(得分:0)
由于您的两个堆栈不是独立的,另一个想法是在单个堆栈上交错数据。例如,您可以为数字使用偶数字,为运算符使用奇数字。
编辑:详细说明评论中要求的想法:我相信每次你推动一个操作员,你就会推动它后面的数字(因为这个数字反过来可能跟着一个更高优先级的算子)。类似地,每次弹出和操作符时,您将弹出两个操作数并推送结果。因此,运算符堆栈和操作数堆栈串联增长和收缩,并且由于最初的问题是如何在汇编代码中执行此操作,我建议它们可以在单个堆栈上共享交替的插槽。 (如果这还不够详细,请告诉我,我会再次编辑。)
答案 4 :(得分:0)
假设表达式的长度为L,则每个堆栈最多为L,因此最多需要2L内存。
将ESP增加2L,在ESP你将有第一个堆栈的开始,在ESP + L你将有第二个堆栈的开始(应该注意这些堆栈都不会超过L因为表达式很长L)。
分流码算法可以在不同的地方找到。它的作用是从中缀符号转换
后缀表示法。之后,对后缀表示法的评估将不会很难。
编辑:另外,为了操纵2个堆栈,你需要将它们的堆栈指针存储在某个地方 您可以使用您选择的2个寄存器,例如EBX,ECX 让一个人拥有ESP值和另一个ESP + L. 每次使用一个堆栈或另一个堆栈时,您必须使用适当的EBX或ECX更新ESP,或者您可以保留2个堆栈指针的任何位置,因为push和pop将修改ESP并且您将希望它们修改ESP的版本需要而不是另一个。当你完成弹出/推送时,你必须用ESP的值更新EBX / ECX。
答案 5 :(得分:-1)
所以,我是否正确创建两个这样的堆栈:
mov ecx,256
L1: call ReadInt
push eax ;push the integer to where esp=1 points
add esp,ecx ;esp=1+256=257, now esp points to 257.
call ReadChar ;read operand
cmp al,endChar ;compare with end sign=$
je next
push al ;push operand to where esp=257 points
sub esp,ecx ;esp=257-256=1, now esp is in the original position
loop L1
next:
...
当然评论是针对第一个循环的。
顺便说一句,我得到了一个“1> .. \ main.asm(46):错误A2149:字节寄存器不能是第一个操作数”错误(push al)?怎么回事?感谢...