Bra*_*ond 1 compiler-construction assembly stack expression-evaluation
我一直在使用教科书来学习汇编语言。我不是在上课,我只是想学汇编语言。在本章末尾,术语之一是“表达式堆栈”。这本书在明确定义关键术语方面往往很差,我无法弄清楚这个术语的确切含义。有人能给我一个相当简洁、直接的解释吗?谢谢你。
为了澄清,这里有更多信息:这一章称为“浮点处理和指令编码”,该部分是关于 FPU 寄存器堆栈的。它提到了这一点:“在后缀表达式的评估过程中,堆栈保存中间值。” 我想知道这是否意味着“表达式堆栈在后缀表达式的评估过程中保存中间值”
在一般情况下,对于复杂的表达式,需要对表达式的片段部分进行计算,然后切换到其他内容,然后在表达式的其他部分中使用这些片段部分的结果。这些零件有时称为中间件或临时件。
例如,以下表达式涉及 2 次乘法和 1 次除法: (a*b)/(c*d)
三地址代码是理解将表达式分解为这些部分的过程的良好开端。在三个地址代码中,我们创建了一个新变量来保存每个单独(行)计算的结果。三地址代码在具有寄存器的机器上的工作方式类似于汇编语言,因为某些操作的顺序是灵活的。
t1 = a*b
t2 = c*d
t3 = t1/t2
Run Code Online (Sandbox Code Playgroud)
使用三个地址代码,我们可以更改顺序:
t2 = c*d
t1 = a*b
t3 = t1/t2
Run Code Online (Sandbox Code Playgroud)
并且代码仍然可以计算正确的答案,因为该行t3=已经明确命名了除法操作数的变量。
如果以系统的方式对表达式求值,例如从左到右(或可重复的),则可以观察到部分表达式求值的中间结果可以存储在堆栈中,而不是随机存储(其中三个地址代码使用通过引入新变量并在使用时显式命名它们来随机存储)。
甲堆栈机上面的表达式的评估将是:
before after
push a stack empty stack has "a"
push b stack has "a" stack has on top "b" then "a" behind
multiply stack has "b", "a" stack has one item: the value of a*b
push c stack has a*b stack has c, then value of a*b
push d stack has c, a*b stack has d, c, a*b
multiply stack has d, c, a*b stack has value of c*d, then value of a*b
divide stack has c*d, a*b stack has value of (a*b)/(c*d)
Run Code Online (Sandbox Code Playgroud)
使用堆栈,我们受到更多限制,这取决于堆栈机器中可用的操作。如果我们颠倒a*band的计算顺序c*d,那么当我们进行除法时,如果我们没有做一些特殊的事情,它会计算(c*d)/(a*b),这是我们不希望看到的。如果硬件指令提供反向除法,我们将使用它;否则我们就必须交换栈顶的两个元素才能使用常规的除法指令。
intel x87浮点单元是一个堆栈机器,它提供类似于 8 个浮点值的堆栈。这些值可以像常规 CPU 寄存器一样快速访问,尽管与常规 CPU 指令不同,这些在此单元中进行浮点计算的指令不指定操作数——它们假设堆栈顶部是它们正在工作的位置(堆栈具有源操作数,目标操作数将返回堆栈)。
由于这个小型硬件堆栈通常用于计算涉及中间结果的复杂表达式,因此有时将其称为表达式堆栈。