鱼C论坛

 找回密码
 立即注册
查看: 2284|回复: 11

对于栈 我好像不放心

[复制链接]
发表于 2015-5-26 01:11:54 | 显示全部楼层 |阅读模式
200鱼币
本帖最后由 Angel丶L 于 2015-5-26 01:58 编辑

1:02:54
whitesilt 2015-5-26 1:02:54



Summer Gull 2015-5-26 1:03:07



Summer Gull 2015-5-26 1:03:12

我一直有个疑问

Summer Gull 2015-5-26 1:03:20

三个变量 放进栈里

Summer Gull 2015-5-26 1:03:32

难道不会拿出来的时候混淆?

whitesilt 2015-5-26 1:03:58

不会

whitesilt 2015-5-26 1:04:03

他是按照顺序放的

Summer Gull 2015-5-26 1:04:43

a
b
c
入栈
c
b
a

取出
c
b
a

file:///C:\Documents and Settings\Administrator\My Documents\Tencent Files\1071729902\Image\C2C\J{4RV$KN_%S4W{GN~FT7R2O.png
whitesilt 2015-5-26 1:05:24

对錒..

Summer Gull 2015-5-26 1:05:35

取出来已经 反过来了

whitesilt 2015-5-26 1:05:36

是用的时候....我们知道栈中的顺序的

whitesilt 2015-5-26 1:05:37

不..

whitesilt 2015-5-26 1:05:42

是编译器知道

Summer Gull 2015-5-26 1:05:48



whitesilt 2015-5-26 1:05:48

他知道顺序

Summer Gull 2015-5-26 1:05:52

那编译器是

whitesilt 2015-5-26 1:05:56

就算反了..他也知道苏醒

whitesilt 2015-5-26 1:05:57

顺序

Summer Gull 2015-5-26 1:06:04

先取出 c b  然后取出a

whitesilt 2015-5-26 1:06:04

知道顺序的

whitesilt 2015-5-26 1:06:06

你放心好了

whitesilt 2015-5-26 1:06:09

不应当

whitesilt 2015-5-26 1:06:11



Summer Gull 2015-5-26 1:06:13

然后 b c再入

whitesilt 2015-5-26 1:06:14

他知道顺序

Summer Gull 2015-5-26 1:06:17

多麻烦啊

Summer Gull 2015-5-26 1:06:27

我学汇编要自己取出

whitesilt 2015-5-26 1:06:28

...........你管它

whitesilt 2015-5-26 1:06:32

.......

Summer Gull 2015-5-26 1:06:54

汇编看到第11了

Summer Gull 2015-5-26 1:07:01

然后对 栈 好不放心

whitesilt 2015-5-26 1:07:20

哦哦

whitesilt 2015-5-26 1:07:24

多熟悉就好了


将就看看 我和谁的聊天记录。。。。
我是这么想的
如果我用汇编语言
那么 只知道栈顶
我取出来 肯定反过来了
怎么办?
编译器知道不关我事啊
我不知道 怎么 找位置啊
5H8`3U{}{B9ZJL%MZ0KB6GW.png
@牡丹花下死做鬼 @kklloo




最佳答案

查看完整内容

楼主 我附上以前学习linux内存时的一张图片 其实栈也好 堆也好 都是内存里的一部分 编译器默认规定了哪个区间是栈区 哪个区间是堆区 堆 栈之间还有一块空闲的地区可供收缩和扩张, 这就是我们平时做的添加元素和删除元素 还有就是栈的增长地址是从高到低 堆得增长是从低到高 这点和我们平常思维里的模式有点相左, 即ss是段的'封顶'地址, sp是根据ss的封顶地址开辟出了一块栈, 然后随着不停的添加元素指针向低地址方向偏 ...
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2015-5-26 01:11:55 | 显示全部楼层
ryxcaixia 发表于 2015-5-26 12:53
如果真想随机获取栈的值
可以强制改变sp或者bp的值进行跨越式存取, 即不按照push和pop的顺序
不过这绝对 ...

楼主 我附上以前学习linux内存时的一张图片
其实栈也好 堆也好 都是内存里的一部分
编译器默认规定了哪个区间是栈区
哪个区间是堆区
堆 栈之间还有一块空闲的地区可供收缩和扩张, 这就是我们平时做的添加元素和删除元素
还有就是栈的增长地址是从高到低
堆得增长是从低到高
这点和我们平常思维里的模式有点相左, 即ss是段的'封顶'地址, sp是根据ss的封顶地址开辟出了一块栈, 然后随着不停的添加元素指针向低地址方向偏

内存布局.PNG
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2015-5-26 08:54:47 | 显示全部楼层
本帖最后由 ryxcaixia 于 2015-5-26 09:04 编辑

首先明确一个问题
栈只是一种存储结构, 先进后出, 比较适用于进制转换等函数, 以及字符串反转等
但是c语言中的栈(包括STL的stack)并不支持随机存取, 即知道了一个元素相对于首地址的下标
可以直接利用Arr[7](G)得到该位置的元素
除非自己重载[]运算符
如果真的是想随机存取, 即通过下标可以索引到元素值, 那么考虑利用其它存储结构如向量容器.
并不一定要执着用栈这种结构
比如链表不支持随机采取, 但是如果非得要链式结构也要支持随机存取, 虽然有点费力不讨好的意思, 但是自己重定义下标操作符也可以做到.
所以重点看你想干什么, 选取合适的存储结构
回归正题, 如果真的想要知道G的位置(我理解为索引号)
先把G刚到一个寄存器里
然后设置个自增计数器如dx, 每次inc一次
从ss:sp~ss:15一直遍历
每次取出的元素与G相减
再设置个条件判断
当遍历取出的元素与G相减为0时
jz条件跳转
然后再看此时计数器的数值就是偏移地址(既然是1~15入栈, 考虑的ASCII最好是对应的字符, 这样就不会有歧义)
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2015-5-26 11:38:20 | 显示全部楼层
ryxcaixia 发表于 2015-5-26 08:54
首先明确一个问题
栈只是一种存储结构, 先进后出, 比较适用于进制转换等函数, 以及字符串反转等
但是c语 ...

如果有重复的呢。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2015-5-26 12:33:45 | 显示全部楼层
栈一般是起临时存储数据的作用的,就是说它会在进栈后很快就会被出栈,如果是写汇编就要自己考虑FILO的顺序。如果要修改和获得不是栈顶的元素,可以用BP存放SP的值然后改变BP的值来达到改变不是栈中不是栈顶元素的数据。这些在小甲鱼汇编后面的视频会提到的
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2015-5-26 12:51:43 | 显示全部楼层
Angel丶L 发表于 2015-5-26 11:38
如果有重复的呢。

有重复的就是取第一个
如果有n个重复的
你在栈上直接
dd n dup(0)
然后si指向重复的首地址
di指向开辟的n个0的首地址
依次赋值
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2015-5-26 12:53:34 | 显示全部楼层
如果真想随机获取栈的值
可以强制改变sp或者bp的值进行跨越式存取, 即不按照push和pop的顺序
不过这绝对不是设计栈的初衷
如果真想随机存取 换个存储结构

评分

参与人数 1荣誉 +10 鱼币 +30 贡献 +2 收起 理由
Angel丶L + 10 + 30 + 2 感谢楼主无私奉献!

查看全部评分

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2015-5-26 14:48:46 | 显示全部楼层
丝雨人 发表于 2015-5-26 12:33
栈一般是起临时存储数据的作用的,就是说它会在进栈后很快就会被出栈,如果是写汇编就要自己考虑FILO的顺序 ...

在第几课?我看书没看小甲鱼的视频
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2015-5-26 15:32:07 | 显示全部楼层
gdb查看指定地址的内存地址的值:examine 简写 x-----使用gdb> help x 来查看使用方式
     x/ (n,f,u为可选参数)
n: 需要显示的内存单元个数,也就是从当前地址向后显示几个内存单元的内容,一个内存单元的大小由后面的u定义
f:显示格式
               x(hex) 按十六进制格式显示变量。
               d(decimal) 按十进制格式显示变量。
               u(unsigned decimal) 按十进制格式显示无符号整型。
               o(octal) 按八进制格式显示变量。
               t(binary) 按二进制格式显示变量。
               a(address) 按十六进制格式显示变量。
               c(char) 按字符格式显示变量。
               f(float) 按浮点数格式显示变量
u:每个单元的大小,按字节数来计算。默认是4 bytes。GDB会从指定内存地址开始读取指定字节,并把其当作一个值取出来,并使用格式f来显示
               b:1 byte     h:2 bytes     w:4 bytes g:8 bytes
     比如x/3uh 0x54320表示从内存地址0x54320读取内容,h表示以双字节为单位,3表示输出3个单位,u表示按照十六进制显示。
    from http://www.cnblogs.com/super119/archive/2011/03/26/1996125.html


gdb打印表达式的值:print/f 表达式
f是输出的格式,x/d/u/o/t/a/c/f

表达式可以是当前程序的const常量,变量,函数等内容,但是GDB不能使用程序中所定义的宏

查看当前程序栈的内容: x/10x $sp-->打印stack的前10个元素
查看当前程序栈的信息: info frame----list general info about the frame
查看当前程序栈的参数: info args---lists arguments to the function
查看当前程序栈的局部变量: info locals---list variables stored in the frame
查看当前寄存器的值:info registers(不包括浮点寄存器) info all-registers(包括浮点寄存器)
查看当前栈帧中的异常处理器:info catch(exception handlers)
from http://blog.chinaunix.net/uid-29062294-id-4255572.html

评分

参与人数 1荣誉 +6 鱼币 +20 贡献 +4 收起 理由
Angel丶L + 6 + 20 + 4 谢啦 看不懂

查看全部评分

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2015-5-26 20:21:03 | 显示全部楼层
Angel丶L 发表于 2015-5-26 14:48
在第几课?我看书没看小甲鱼的视频

如果你知道入栈的顺序和入栈的数据的长度类型,可以根据栈顶加上便宜地址寻到你所要的G变量。比如栈顶是2001,数据是 byte类型,G是第7个数据,一共15个数据,那么G的相对于栈顶的偏移地址就是15-7=8,就可以得出G在[2001]+[8]=[2009]处。栈就一个特点。FILO    先进后出,想通这个然后在考虑不要溢出就可以了
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2015-5-27 00:12:59 | 显示全部楼层
支持一个哦
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2015-7-8 23:46:25 | 显示全部楼层
thank you
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-10-6 22:18

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表