关于出栈的疑惑

2020-07-08 09:39:44 +08:00
 linxiaoziruo

假设有一个函数是这样的 void demo(){ int a = 1; int b = 2; int c = 3;

int d = a * b; int e = c* d; }

理论上应该 a 先入栈,其次 b,c ;出栈的时候是 a,b 先出栈(应为先用到他们两),既然 a,b 先出栈,那么 c 肯定也用出栈(删除),那么首次用到 c 对时候,c 从哪儿去取呢(应为已经出栈被删除掉了)?

3831 次点击
所在节点    Java
25 条回复
ChanKc
2020-07-08 10:01:08 +08:00
出栈?你这个代码编译器可以重排序的
dddddddddd
2020-07-08 10:25:14 +08:00
?? 出栈处理的不是单个变量吧,函数退出的时候,应该是整个函数一次性退出。Java 里面这个东西叫栈帧,不知道 C 语言里的名词是啥。
GuuJiang
2020-07-08 10:29:51 +08:00
请先定义你这里说的栈指的是函数调用时传递参数的那个栈,还是 opcode 的操作栈,但无论哪个都不存在你说的这个疑惑,无意冒犯,不过你的这个提问给人感觉你似乎隐隐约约走上了思而不学的路子
kop1989
2020-07-08 10:33:17 +08:00
不太懂 c 语言,但是 java 的话,你调用 a 和 b,a 和 b 并未出栈,只是你使用了 a 和 b 的指针。
所以你这个疑惑意义不明。
zifangsky
2020-07-08 10:36:37 +08:00
0 iconst_1
1 istore_1
2 iconst_2
3 istore_2
4 iconst_3
5 istore_3
6 iload_1
7 iload_2
8 imul
9 istore 4
11 iload_3
12 iload 4
14 imul
15 istore 5
17 return

执行完第 5 行之后,此时局部变量表中有:
0 this
1 1
2 2
3 3

执行第 6 7 行,本质上就是将局部变量表中的 1 和 2 先后取出来放在操作数栈中,然后第 8 行的 imul 指令就是从操作数栈中弹出两个元素做乘法,并将结果再压回操作数栈。

执行第 9 行,这里的 istore 指令的意思是从操作数栈中出栈一个元素存到局部变量表中的第 4 个位置。后面指令的意思差不多,就不做过多解释了。

结论:以上代码的乘法计算过程不是直接从本地线程栈中出栈做计算,而是①从局部变量表中取数据压到操作数栈,然后②从操作数栈中弹出元素做计算并将结果再压回操作数栈,最后③如果有赋值操作就将其再存到局部变量表中的对应位置。
ConradG
2020-07-08 10:39:59 +08:00
数据结构的栈和内存空间的栈是除了名字相同之外没啥关系的两个东西。
Jooooooooo
2020-07-08 10:49:37 +08:00
重新看书吧

完全理解错了, 基本概念也不懂
sivacohan
2020-07-08 11:08:23 +08:00
@dddddddddd 也叫栈栈帧
fxxwor99LVHTing
2020-07-08 11:13:32 +08:00
这里面的算术运算和‘出栈’有什么关系?
LennieChoi
2020-07-08 11:20:29 +08:00
不是一个栈哦,函数体内声明的变量是存在栈内存,不是栈数据结构,函数传参才会以栈结构的方式存入内存
WessonC
2020-07-08 11:24:58 +08:00
不好意思,看成了出柜。
dangyuluo
2020-07-08 11:30:31 +08:00
@Jooooooooo +1

如果懒得看书的话,建议楼主看一下编译出来的汇编码
serical
2020-07-08 11:31:14 +08:00
@WessonC 哈哈哈哈, 关于出柜的疑惑
zst
2020-07-08 12:43:47 +08:00
@serical @WessonC 你们不是一个人哈哈哈
yeqizhang
2020-07-08 13:00:11 +08:00
建议多理解 5 楼的字节码
chenchunyu
2020-07-08 14:51:58 +08:00
《深入理解计算机系统》 3.7 节:过程
TuYanzheng
2020-07-08 15:03:15 +08:00
@WessonC 我也是哈哈哈
AlohaV2
2020-07-08 16:29:59 +08:00
memory order
tairan2006
2020-07-08 16:38:55 +08:00
看汇编代码
hhhWhy
2020-07-08 17:07:20 +08:00
整体压入栈内存,然后通过指针(地址)访问,最后整体出栈

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/688110

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX