免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
123下一页
最近访问板块 发新帖
查看: 11027 | 回复: 22
打印 上一主题 下一主题

那位大牛能详细解释下硬件堆栈和软件堆栈? [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2007-10-19 19:01 |只看该作者 |倒序浏览
那位大牛能详细解释下硬件堆栈和软件堆栈?

论坛徽章:
0
2 [报告]
发表于 2007-10-19 19:09 |只看该作者
我觉得堆栈只是一个概念, 具体的实现应该是硬件提供了相应的支持, 而由软件去实施.
在8086实模式下编写汇编的时候, 使用的push, pop指令都是对寄存器的一种隐式的操作. 证明其硬件提供了相应的机制 . 但是何时使用堆栈, 却是你软件人员需要考虑的.
对于堆栈段, 既可以与代码段相同, 也可以分离出去. 在硬件上来说, 不过是ss这个寄存器所指定的段基址而已.

呵呵, 个人所见. 也望高手指教!

论坛徽章:
36
IT运维版块每日发帖之星
日期:2016-04-10 06:20:00IT运维版块每日发帖之星
日期:2016-04-16 06:20:0015-16赛季CBA联赛之广东
日期:2016-04-16 19:59:32IT运维版块每日发帖之星
日期:2016-04-18 06:20:00IT运维版块每日发帖之星
日期:2016-04-19 06:20:00每日论坛发贴之星
日期:2016-04-19 06:20:00IT运维版块每日发帖之星
日期:2016-04-25 06:20:00IT运维版块每日发帖之星
日期:2016-05-06 06:20:00IT运维版块每日发帖之星
日期:2016-05-08 06:20:00IT运维版块每日发帖之星
日期:2016-05-13 06:20:00IT运维版块每日发帖之星
日期:2016-05-28 06:20:00每日论坛发贴之星
日期:2016-05-28 06:20:00
3 [报告]
发表于 2007-10-19 19:17 |只看该作者
scutan兄月学越深入了啊,赞一个

原帖由 scutan 于 2007-10-19 19:09 发表
我觉得堆栈只是一个概念, 具体的实现应该是硬件提供了相应的支持, 而由软件去实施.
在8086实模式下编写汇编的时候, 使用的push, pop指令都是对寄存器的一种隐式的操作. 证明其硬件提供了相应的机制 . 但是何时 ...

论坛徽章:
0
4 [报告]
发表于 2007-10-19 19:20 |只看该作者
原帖由 Godbach 于 2007-10-19 19:17 发表
scutan兄月学越深入了啊,赞一个



兄台过奖了. 只是最近越学越觉得底层方面的内容是那么地重要.

论坛徽章:
36
IT运维版块每日发帖之星
日期:2016-04-10 06:20:00IT运维版块每日发帖之星
日期:2016-04-16 06:20:0015-16赛季CBA联赛之广东
日期:2016-04-16 19:59:32IT运维版块每日发帖之星
日期:2016-04-18 06:20:00IT运维版块每日发帖之星
日期:2016-04-19 06:20:00每日论坛发贴之星
日期:2016-04-19 06:20:00IT运维版块每日发帖之星
日期:2016-04-25 06:20:00IT运维版块每日发帖之星
日期:2016-05-06 06:20:00IT运维版块每日发帖之星
日期:2016-05-08 06:20:00IT运维版块每日发帖之星
日期:2016-05-13 06:20:00IT运维版块每日发帖之星
日期:2016-05-28 06:20:00每日论坛发贴之星
日期:2016-05-28 06:20:00
5 [报告]
发表于 2007-10-19 19:45 |只看该作者

回复 #4 scutan 的帖子

呵呵,知识越学越觉得要学的太多了。学然后知不足啊!

论坛徽章:
0
6 [报告]
发表于 2007-10-19 20:40 |只看该作者
有篇文章上是这样定义的:if a cpu provides an Explicit stack pointer register, we say that CPU supports a hardware stack; if only a general purpose register is available, then we say that CPU uses a software implemented stack  
记得以前在移植ucos时,ucos可移植的要求之一就是cpu要支持一定的硬件堆栈,可能几KB。pc机和arm上都有类似的压栈,出栈指令,像sparc体系的cpu编译器一般是把o6这个通用寄存器作为栈指针,当然编译器应该也是可以用其他的,那么感觉按照上面英文的硬件堆栈定义,ucos在sparc上就不可以跑,但是事实证明确实可以的,到底是ucos上面的要求写的过于苛刻还是对于软/硬件堆栈的理解有误呢?

论坛徽章:
0
7 [报告]
发表于 2007-10-19 21:43 |只看该作者
原帖由 scutan 于 2007-10-19 19:09 发表
我觉得堆栈只是一个概念, 具体的实现应该是硬件提供了相应的支持, 而由软件去实施.
在8086实模式下编写汇编的时候, 使用的push, pop指令都是对寄存器的一种隐式的操作. 证明其硬件提供了相应的机制 . 但是何时 ...

首先无论是实模式还是保护模式,push和pop指令都是可用的,只是前者操作的是物理地址,后者是虚拟地址。
通常我们说栈都是指软件栈。一般处理器提供一个栈指针寄存器,通过加或减栈指针寄存器的值,来减小或扩大程序的栈。栈指针的值是个地址(在保护模式下是虚拟地址,在是模式下是物理地址)。在linux下栈指针初值是0xbfffffff,也就是用户空间的顶端,它向下增长(这是对于x86来说的,其它架构栈指针从哪儿开始、向什么方向增长取决于操作系统的地址空间布局和架构的是little-endian还是big-endian)。需要注意的是,栈指针变化并不能真正扩大和减小程序栈所占的物理内存。例如栈指针减小了4k(注意x86栈是向下增长,栈指针减表示栈扩大了),程序的栈就扩大了4k,但这个时候这4k的栈并非真有物理内存和它对应,只有当程序第一访问该4k的栈时,产生了一个page fault,操作系统才会真正的分配物理页并修改程序的页表。
对于使用段模式情况下,x86中的esp是个偏移,和SS相加得到栈指针。当使用纯的页模式(x86_64使用,由于去掉了段保护,所以SS通常为0),SS为0时,esp就是栈指针。(这一段如果有错请纠正,我对x86不是特别熟悉,可能有误)

我不知道有没有硬件栈的说法,但确实有寄存器栈的说法。寄存器栈,对于x86来说就是所有可用的通用寄存器的总和,也就是eax、ebx、ecx、edx、esi、edi,通常当变量的个数过多,寄存器不够使用而需要存在内存栈上时,我们称为寄存器栈溢出。对于一些RISC架构,例如sparic、IA64,由于通用寄存器特别多,寄存器栈代表当前函数使用的通用寄存器总和,也叫寄存器帧、寄存器窗。例如一个函数有3个输入参数、2个局部变量、4个输出变量(输出变量是被调用函数的输入,即参数),在这些架构上会分配一共9个寄存器供当前函数使用,这些寄存器就称为当前寄存器栈。这个栈也是变化的,当函数中调用另一个函数,上一个函数的输出寄存器成为下一个函数的输入寄存器(即参数),下一个函数又再自行分配新的寄存器存放局部变量和输出变量,构成新的当前寄存器栈。因为这种行为就像一个窗从左向右滑动,所以又称为寄存器窗。

论坛徽章:
0
8 [报告]
发表于 2007-10-19 23:10 |只看该作者
zx_wing...so great
不过sparic应该是sparc的笔误吧,对RISC那一段的总结很好啊

[ 本帖最后由 DesignInside 于 2007-10-19 23:18 编辑 ]

论坛徽章:
0
9 [报告]
发表于 2007-10-20 11:12 |只看该作者
原帖由 zx_wing 于 2007-10-19 21:43 发表

首先无论是实模式还是保护模式,push和pop指令都是可用的,只是前者操作的是物理地址,后者是虚拟地址。
通常我们说栈都是指软件栈。一般处理器提供一个栈指针寄存器,通过加或减栈指针寄存器的值,来减小或 ...


>>首先无论是实模式还是保护模式,push和pop指令都是可用的,只是前者操作的是物理地址,后者是虚拟地址

实际上也不能说实模式下操作的是物理地址,物理地址都需要 MMU 进行转换。
实模式与保扩模式下的段机制并无两样。实模式与保扩模式下的程序使用都是逻辑地址,也就是说:segment : offset 这种形式。这种形式的地址都经过段机制转换为线性地址。实模式下就是物理地址,保护模式下没开启分页也为物理地址,在开启分页后是虚拟地址。

不同的是:
如:ds:1234   实模式下,ds.base addr 被加载为 ds << 4 这个值,limit 都是 FFFF
                      保护模式下, ds.base addr 根据 selector 的值找到相应 descriptor 来加载相应的值。



>> 对于x86来说的,其它架构栈指针从哪儿开始、向什么方向增长取决于操作系统的地址空间布局和架构的是little-endian还是big-endian

实际上向什么方向增长并不是由操作系统和 endian 关系来决定。而是由 stack segment  的 descriptor 属性来决定。segment 的 descriptor 有个标志位 D/B 决定这个段是 expand-up 还是 expand-down


>> x86_64使用,由于去掉了段保护,所以SS通常为0,SS为0时,esp就是栈指针
x86_64 基本上去掉了段机制,但这不是完全的。CS、DS、SS 及ES 已经被忽略。除了 CS 的某些属性可用外。 FS/GS 还是可以用于段机制来管理。所有的内存参考都是基于 0 。RSP 确实是实际的线指针。





关于硬件栈与软件栈的看法:

一、在使用上
由 ss 与 esp 组成的栈结构已经可以算是硬件栈了,它们的 pop/push 行为都是由处理器去维护了。
软件栈:软件可以自己定义一个数据结构,pop/push 行为需由软件去维护,如:栈顶和栈底、栈空和栈满等的维护。

二、从物理上
若要从物理上去定义硬件栈结构,恐怕只有 X86 才有真正的硬件栈结构。那就是 x86 独特的浮点寄存器堆结构:
由 FR0 ~ FR7 浮点寄存器组成的一个浮点寄存栈结构。栈指针是:x87 的 status word 寄存器中有一个 top 域来指出栈顶,也就是逻辑上 ST(0) 就是栈顶,它可以对应 FR0~FR7 任一个寄存器。x87 的这个栈结构像一个圆形的环,栈满会自动回卷



不对的敬请指出!

.

[ 本帖最后由 mik 于 2007-10-20 11:14 编辑 ]

论坛徽章:
0
10 [报告]
发表于 2007-10-20 11:55 |只看该作者
提示: 作者被禁止或删除 内容自动屏蔽
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP