对于栈 我好像不放心
本帖最后由 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
多熟悉就好了
将就看看 我和谁的聊天记录。。。。
我是这么想的
如果我用汇编语言
那么 只知道栈顶
我取出来 肯定反过来了
怎么办?
编译器知道不关我事啊
我不知道 怎么 找位置啊
@牡丹花下死做鬼 @kklloo
ryxcaixia 发表于 2015-5-26 12:53
如果真想随机获取栈的值
可以强制改变sp或者bp的值进行跨越式存取, 即不按照push和pop的顺序
不过这绝对 ...
楼主 我附上以前学习linux内存时的一张图片
其实栈也好 堆也好 都是内存里的一部分
编译器默认规定了哪个区间是栈区
哪个区间是堆区
堆 栈之间还有一块空闲的地区可供收缩和扩张, 这就是我们平时做的添加元素和删除元素
还有就是栈的增长地址是从高到低
堆得增长是从低到高
这点和我们平常思维里的模式有点相左, 即ss是段的'封顶'地址, sp是根据ss的封顶地址开辟出了一块栈, 然后随着不停的添加元素指针向低地址方向偏
本帖最后由 ryxcaixia 于 2015-5-26 09:04 编辑
首先明确一个问题
栈只是一种存储结构, 先进后出, 比较适用于进制转换等函数, 以及字符串反转等
但是c语言中的栈(包括STL的stack)并不支持随机存取, 即知道了一个元素相对于首地址的下标
可以直接利用Arr(G)得到该位置的元素
除非自己重载[]运算符
如果真的是想随机存取, 即通过下标可以索引到元素值, 那么考虑利用其它存储结构如向量容器.
并不一定要执着用栈这种结构
比如链表不支持随机采取, 但是如果非得要链式结构也要支持随机存取, 虽然有点费力不讨好的意思, 但是自己重定义下标操作符也可以做到.
所以重点看你想干什么, 选取合适的存储结构
回归正题, 如果真的想要知道G的位置(我理解为索引号)
先把G刚到一个寄存器里
然后设置个自增计数器如dx, 每次inc一次
从ss:sp~ss:15一直遍历
每次取出的元素与G相减
再设置个条件判断
当遍历取出的元素与G相减为0时
jz条件跳转
然后再看此时计数器的数值就是偏移地址(既然是1~15入栈, 考虑的ASCII最好是对应的字符, 这样就不会有歧义)
ryxcaixia 发表于 2015-5-26 08:54
首先明确一个问题
栈只是一种存储结构, 先进后出, 比较适用于进制转换等函数, 以及字符串反转等
但是c语 ...
如果有重复的呢。 栈一般是起临时存储数据的作用的,就是说它会在进栈后很快就会被出栈,如果是写汇编就要自己考虑FILO的顺序。如果要修改和获得不是栈顶的元素,可以用BP存放SP的值然后改变BP的值来达到改变不是栈中不是栈顶元素的数据。这些在小甲鱼汇编后面的视频会提到的 Angel丶L 发表于 2015-5-26 11:38
如果有重复的呢。
有重复的就是取第一个
如果有n个重复的
你在栈上直接
dd n dup(0)
然后si指向重复的首地址
di指向开辟的n个0的首地址
依次赋值 如果真想随机获取栈的值
可以强制改变sp或者bp的值进行跨越式存取, 即不按照push和pop的顺序
不过这绝对不是设计栈的初衷
如果真想随机存取 换个存储结构 丝雨人 发表于 2015-5-26 12:33
栈一般是起临时存储数据的作用的,就是说它会在进栈后很快就会被出栈,如果是写汇编就要自己考虑FILO的顺序 ...
在第几课?我看书没看小甲鱼的视频 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 Angel丶L 发表于 2015-5-26 14:48
在第几课?我看书没看小甲鱼的视频
如果你知道入栈的顺序和入栈的数据的长度类型,可以根据栈顶加上便宜地址寻到你所要的G变量。比如栈顶是2001,数据是 byte类型,G是第7个数据,一共15个数据,那么G的相对于栈顶的偏移地址就是15-7=8,就可以得出G在+=处。栈就一个特点。FILO 先进后出,想通这个然后在考虑不要溢出就可以了 支持一个哦 thank you
页:
[1]