【发布时间】:2015-04-26 23:45:26
【问题描述】:
我想在汇编中制作一个计算器,它接受算术表达式并输出结果。
类似:
((3 +7) * 21) - (45 -99)
然后我想我需要两个堆栈:一个用于推动数字,另一个用于推动左括号。
但是我四处搜索并没有结果。回答类似问题的人认为这是一个坏主意,因为有内置堆栈。
所以我的问题是:使用另一个堆栈是个坏主意吗?如果是的话,什么是实现这个的好方法。谢谢
【问题讨论】:
我想在汇编中制作一个计算器,它接受算术表达式并输出结果。
类似:
((3 +7) * 21) - (45 -99)
然后我想我需要两个堆栈:一个用于推动数字,另一个用于推动左括号。
但是我四处搜索并没有结果。回答类似问题的人认为这是一个坏主意,因为有内置堆栈。
所以我的问题是:使用另一个堆栈是个坏主意吗?如果是的话,什么是实现这个的好方法。谢谢
【问题讨论】:
如果您可以拥有有限堆栈,您可以更改rbp 和rsp 并在堆栈中保留一些空间,然后您可以像数组一样使用它,或者您可以使用一些全局分配的数组,而不是在堆栈中保留空间
如果你必须有无限堆栈,你必须使用链表,在 linux 中你必须使用类似br() 的系统调用来在堆中保留空间,或者你可以使用 C 库函数 malloc() 来为你做这件事。
这是 GAS 语法中有限堆栈的简单实现(由 GCC 由 C 源代码生成)
.local S
.comm S,4096,32
.local head
.comm head,4,4
.text
.globl push
push:
.LFB0:
pushq %rbp
movq %rsp, %rbp
movl %edi, -4(%rbp)
movl head(%rip), %eax
cmpl $1023, %eax
jg .L1
movl head(%rip), %eax
cltq
movl -4(%rbp), %edx
movl %edx, S(,%rax,4)
movl head(%rip), %eax
addl $1, %eax
movl %eax, head(%rip)
.L1:
popq %rbp
ret
.LFE0:
.globl pop
pop:
.LFB1:
pushq %rbp
movq %rsp, %rbp
movl head(%rip), %eax
testl %eax, %eax
jle .L4
movl head(%rip), %eax
subl $1, %eax
movl %eax, head(%rip)
movl head(%rip), %eax
cltq
movl S(,%rax,4), %eax
jmp .L3
.L4:
.L3:
popq %rbp
ret
在上面的代码中,S 是我们全局定义的堆栈数组,head 是我们的堆栈头并再次全局定义。
【讨论】: