求助 汇编 多个栈怎么用

lingling1989r 2009-06-17 10:34:56
为了能用多个栈,我的部分代码如下

data segment

bottom db '@'
info1 db 0dh,0ah,'it can only program about * or + $'
info2 db 0dh,0ah,'input your expresion ','and press q to exit $'
left db 0
right db 0
result dw 0
data ends

numstack segment stack
db 200 dup(0)
numstack ends
opstack segment
db 200 dup(0)
opstack ends

code segment
assume ds:data ,ss:numstack,cs:code

start:
mov ax,data
mov ds,ax

;将‘@’放到各个栈的栈底,不知道栈转换是这么用的么。
mov ax,numstack
mov ss,ax
push bottom
mov ax,opstack
mov ss,ax
push bottom

mov ax,'+'
push ax

mov ax,numstack
mov ss,ax
mov ax,3
push ax
mov ax,4
push ax
pop left
pop right


mov ax,opstack
mov ss,ax
pop bx
cmp bx,'+'
jne exit
mov ax,left
add ax,right
mov result,ax
exit:
mov ah,4ch
int 21h
code ends
end start


问题二:为什么每次mov ss,ax,debug的时候,sp指针会下移??
问题三:我换用另一个栈的时候,为什么sp仍是按照原来的那个栈的sp的值下移的呢?

讲的越清楚越好,刚开始看书,各种的不懂啊!!
...全文
263 23 打赏 收藏 转发到动态 举报
写回复
用AI写文章
23 条回复
切换为时间正序
请发表友善的回复…
发表回复
uwinb 2009-06-20
  • 打赏
  • 举报
回复
系统栈不是给你用来存放数字和运算符号的,它是用来跟踪程序的执行流程,比较多的用于跳转前后保存或恢复现场,以及在模块间传递参数。
而你的数字和运算符号应该存放到数组中去,也就是定义两块内存和两个偏移变量实现你自定义的“栈”,和高级语言中的数组是一个意思。

系统栈和高级语言中所谓的“栈”完全是两码事,显而易见的区别就是前者由机器直接支持,当系统栈溢出时会诱发很不友好的蓝屏警告,因为没有更底层的机制来预测和控制这一切(当然可以认为CPU为了支持debug提供了貌似局外人的“观察者”模式)。
而你在高级语言中自己定义的“栈”就不一样了,你可以随意控制它的大小,可以决定在它空了或满了的时候该怎么响应它的调用者(抛异常、阻塞或扩空间等等)。

lingling1989r 2009-06-20
  • 打赏
  • 举报
回复
[Quote=引用 20 楼 uwinb 的回复:]
系统栈不是给你用来存放数字和运算符号的,它是用来跟踪程序的执行流程,比较多的用于跳转前后保存或恢复现场,以及在模块间传递参数。
而你的数字和运算符号应该存放到数组中去,也就是定义两块内存和两个偏移变量实现你自定义的“栈”,和高级语言中的数组是一个意思。

系统栈和高级语言中所谓的“栈”完全是两码事,显而易见的区别就是前者由机器直接支持,当系统栈溢出时会诱发很不友好的蓝屏警告,因为没有更底层的机…
[/Quote]

其实最开始写的时候想过要用数组的(我意思是说,在数据段里开一段数据空间用来当我的栈来用),可是又不大懂怎么写出这个东西能让它做栈的工作。所以作罢。能具体点么???是怎么弄出来的。
lingling1989r 2009-06-20
  • 打赏
  • 举报
回复
[Quote=引用 11 楼 Tippisum 的回复:]
引用 10 楼 lingling1989r 的回复:
恩,学习了。我写了个运算器,暂时先只能实现,+和*和()运算。

因为是两个栈,所以我可以用bp和sp之间相互转换来用这两个栈。

再补问一个问题:高级语言(那c来说)编译成汇编的时候,多个栈是怎么分配的??



哪来的多个栈,明明就只有一个栈。(其他的“栈”都是你自己定义的数据结构,跟真正的栈没关系。高级语言不可能允许你操作系统栈的。别的不说,你一个pop就可以让整…
[/Quote]
你没明白我意思,我是说,我知道只有一个sp指针,所以我用sp和bp轮回交换着,是不是可以Pop了。我想用哪个栈,我就把sp给换过去。这样是不是可以了??你说崩溃是怎么崩溃的???你具体崩溃下,我不太明白你说的pop崩溃。
Tippisum 2009-06-20
  • 打赏
  • 举报
回复
高级语言的“栈”实际上说白了就是特殊数组,跟系统内部的栈没有任何关系。
BAYNPU 2009-06-19
  • 打赏
  • 举报
回复
这个二个网页让楼主参考吧,也许对你有一定帮助。
http://zhidao.baidu.com/question/23516539.html
http://blog.sina.com.cn/s/blog_4bb4614f0100antr.html
lingling1989r 2009-06-19
  • 打赏
  • 举报
回复
不是是多个段的分配,是多个栈的分配。
lingling1989r 2009-06-18
  • 打赏
  • 举报
回复
恩,学习了。我写了个运算器,暂时先只能实现,+和*和()运算。

因为是两个栈,所以我可以用bp和sp之间相互转换来用这两个栈。

再补问一个问题:高级语言(那c来说)编译成汇编的时候,多个栈是怎么分配的??
nanlingcg 2009-06-18
  • 打赏
  • 举报
回复
用2个栈???好玩。。。
1个栈不够用啊?够用只调整SP比调整SS+SP要精简些。。。
lingling1989r 2009-06-18
  • 打赏
  • 举报
回复
[Quote=引用 15 楼 schlafenhamster 的回复:]
当初16位时,“调试器”本身使用自己的栈(现在可能也有这样的),到32位保护模式下,就有“任务门”的概念了,它把当前运行环境都保存起来了(包括SS:SP)。那就不止2个栈了。
[/Quote]

举例说明吧。我也想过把他们存进去,可是我存进去之后开始用另一个栈,那我在用这个栈的时候,想用那个栈,我该怎么去取,我不知道它存入的地址和我现在的sp的相对差值,我怎么获得啊。

呵呵,学习向上~~、
周一结贴。
wxgiter 2009-06-18
  • 打赏
  • 举报
回复
没试过多个栈
关注+学习。。
schlafenhamster 2009-06-18
  • 打赏
  • 举报
回复
当初16位时,“调试器”本身使用自己的栈(现在可能也有这样的),到32位保护模式下,就有“任务门”的概念了,它把当前运行环境都保存起来了(包括SS:SP)。那就不止2个栈了。
lingling1989r 2009-06-18
  • 打赏
  • 举报
回复
李某某,你不要吵!我是没清楚物理内存之间的关系。你具体说说吧。
我现在已经知道因为只有一个sp栈顶寄存器,所以只能一个栈,我现在想问的是:高级语言(c为例)编译后,我多个stack,它编译出的是个怎么的样子。该怎么的分配?
我到下周一结贴。
光宇广贞 2009-06-18
  • 打赏
  • 举报
回复
楼主似乎还是没有搞明白——概念上的“栈”和实际的物理内存存在之间的关系。
光宇广贞 2009-06-18
  • 打赏
  • 举报
回复
?呵呵……楼主还在尝试多个栈呐……

支持,支持……

不走到死胡同是不知道不可行的。

不过鼓励尝试精神。
Tippisum 2009-06-18
  • 打赏
  • 举报
回复
[Quote=引用 10 楼 lingling1989r 的回复:]
恩,学习了。我写了个运算器,暂时先只能实现,+和*和()运算。

因为是两个栈,所以我可以用bp和sp之间相互转换来用这两个栈。

再补问一个问题:高级语言(那c来说)编译成汇编的时候,多个栈是怎么分配的??
[/Quote]

哪来的多个栈,明明就只有一个栈。(其他的“栈”都是你自己定义的数据结构,跟真正的栈没关系。高级语言不可能允许你操作系统栈的。别的不说,你一个pop就可以让整个程序崩溃(过程找不到返回地址了!)

Win32程序里面每个线程都可以有一个栈,但这是靠CPU任务切换时自动加载存放在TSS里面的SS和ESP来完成的,基本上程序本身不会开几个栈然后在里面跳来跳去。
lingling1989r 2009-06-17
  • 打赏
  • 举报
回复
算了,我还是在一个栈里折腾吧,换个栈的时候就用sp+100来换。这样自己还清楚些。
还不打算结贴。
还是多给点建议吧。帮解决下我上面的问题。谢谢!
光宇广贞 2009-06-17
  • 打赏
  • 举报
回复
顶一个。
lingling1989r 2009-06-17
  • 打赏
  • 举报
回复
第二个问题,debug下的时候它似乎把push bottom给屏蔽掉了,我也觉得没有道理。可能是这个原因导致的吧。想截图给你看的,放不上来。
我问第三个问题:
如果是那样的话,opstack 的sp=00c4,push完之后,我换到numstack的时候sp不变的话,那我去pop的时候,执行sp+2那我得到的就不是我想要得到的值了。
gzgzlxg 2009-06-17
  • 打赏
  • 举报
回复
在intel的8086 cpu系列中,mov ss, xx 指令执行时,自动屏蔽中断,同时自动加载 sp。在debug中,不能够单步执行 mov ss, xx/mov sp,xx指令,意味着,这两个指令只能被同时执行,这不是debug的功能,而是cpu的正常行为。
试想,如果你单独执行mov ss, xx或单独执行mov sp, xx,会出现什么情况?
例如,在一个中断过程发生前,ss作为系统栈,sp为当前系统堆栈指针,中断发生后,用户修改了ss堆栈段的地址到用户区,而sp还是系统堆栈的指针,这个时候如果发生堆栈操作,会发生什么情况?其结果就是天下大乱。
所以在写程序时,如果使用堆栈操作,请养成习惯,将mov ss, xx/mov sp, xx指令成对出现,前几天看到某位写的程序,就将这些指令分开写,不过当时我实在懒的写。
今天之所以做出这些说明,源于楼上的“Debug遇到修改ss的指令时会连同下一条指令一起执行”这句话。个人觉得有必要对此做一个清楚的说明。
cnzdgs 2009-06-17
  • 打赏
  • 举报
回复
栈顶指针是由ss和sp共同表示的,两个都要改,只改ss很可能会出问题。Debug遇到修改ss的指令时会连同下一条指令一起执行,(Debug认为下一条指令是修改sp的),以免中断时由于栈无效而破坏其它数据。
加载更多回复(2)

21,500

社区成员

发帖
与我相关
我的任务
社区描述
汇编语言(Assembly Language)是任何一种用于电子计算机、微处理器、微控制器或其他可编程器件的低级语言,亦称为符号语言。
社区管理员
  • 汇编语言
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧