V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
linxiaoziruo
V2EX  ›  Java

关于出栈的疑惑

  •  
  •   linxiaoziruo · 2020 年 7 月 8 日 · 4338 次点击
    这是一个创建于 2024 天前的主题,其中的信息可能已经有所发展或是发生改变。

    假设有一个函数是这样的 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 从哪儿去取呢(应为已经出栈被删除掉了)?

    25 条回复    2020-07-10 11:28:50 +08:00
    ChanKc
        1
    ChanKc  
       2020 年 7 月 8 日 via Android
    出栈?你这个代码编译器可以重排序的
    dddddddddd
        2
    dddddddddd  
       2020 年 7 月 8 日
    ?? 出栈处理的不是单个变量吧,函数退出的时候,应该是整个函数一次性退出。Java 里面这个东西叫栈帧,不知道 C 语言里的名词是啥。
    GuuJiang
        3
    GuuJiang  
       2020 年 7 月 8 日 via iPhone   ❤️ 1
    请先定义你这里说的栈指的是函数调用时传递参数的那个栈,还是 opcode 的操作栈,但无论哪个都不存在你说的这个疑惑,无意冒犯,不过你的这个提问给人感觉你似乎隐隐约约走上了思而不学的路子
    kop1989
        4
    kop1989  
       2020 年 7 月 8 日 via iPhone
    不太懂 c 语言,但是 java 的话,你调用 a 和 b,a 和 b 并未出栈,只是你使用了 a 和 b 的指针。
    所以你这个疑惑意义不明。
    zifangsky
        5
    zifangsky  
       2020 年 7 月 8 日   ❤️ 2
    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
        6
    ConradG  
       2020 年 7 月 8 日   ❤️ 3
    数据结构的栈和内存空间的栈是除了名字相同之外没啥关系的两个东西。
    Jooooooooo
        7
    Jooooooooo  
       2020 年 7 月 8 日
    重新看书吧

    完全理解错了, 基本概念也不懂
    sivacohan
        8
    sivacohan  
    PRO
       2020 年 7 月 8 日
    @dddddddddd 也叫栈栈帧
    fxxwor99LVHTing
        9
    fxxwor99LVHTing  
       2020 年 7 月 8 日
    这里面的算术运算和‘出栈’有什么关系?
    LennieChoi
        10
    LennieChoi  
       2020 年 7 月 8 日
    不是一个栈哦,函数体内声明的变量是存在栈内存,不是栈数据结构,函数传参才会以栈结构的方式存入内存
    WessonC
        11
    WessonC  
       2020 年 7 月 8 日   ❤️ 3
    不好意思,看成了出柜。
    dangyuluo
        12
    dangyuluo  
       2020 年 7 月 8 日
    @Jooooooooo +1

    如果懒得看书的话,建议楼主看一下编译出来的汇编码
    serical
        13
    serical  
       2020 年 7 月 8 日
    @WessonC 哈哈哈哈, 关于出柜的疑惑
    zst
        14
    zst  
       2020 年 7 月 8 日
    @serical @WessonC 你们不是一个人哈哈哈
    yeqizhang
        15
    yeqizhang  
       2020 年 7 月 8 日 via Android
    建议多理解 5 楼的字节码
    chenchunyu
        16
    chenchunyu  
       2020 年 7 月 8 日 via iPad
    《深入理解计算机系统》 3.7 节:过程
    TuYanzheng
        17
    TuYanzheng  
       2020 年 7 月 8 日
    @WessonC 我也是哈哈哈
    AlohaV2
        18
    AlohaV2  
       2020 年 7 月 8 日 via iPhone
    memory order
    tairan2006
        19
    tairan2006  
       2020 年 7 月 8 日 via Android
    看汇编代码
    hhhWhy
        20
    hhhWhy  
       2020 年 7 月 8 日
    整体压入栈内存,然后通过指针(地址)访问,最后整体出栈
    hhhWhy
        21
    hhhWhy  
       2020 年 7 月 8 日
    @hhhWhy 指针相对地址一般在编译的时候就会生成,只需要读栈顶就能知道变量地址
    zsdroid
        22
    zsdroid  
       2020 年 7 月 8 日
    变量没有栈吧,方法才有栈,方法里的局部变量都属于栈里的一块数据。
    xe2vherd
        23
    xe2vherd  
       2020 年 7 月 8 日
    用到 a,b 为什么要 a,b 出栈.
    a 的地址大概为 12(%esp)
    b 的地址大概为 8(%esp)
    linxiaoziruo
        24
    linxiaoziruo  
    OP
       2020 年 7 月 9 日
    Java 为什么用堆来组织内存数据,有什么好处吗,具体对好处对场景是什么?为什么不用平衡树或者链表来组织内存数据?
    AlohaV2
        25
    AlohaV2  
       2020 年 7 月 10 日 via iPhone
    @linxiaoziruo 这个堆不是你说的堆。heap memory 不等于 heap
    关于   ·   帮助文档   ·   自助推广系统   ·   博客   ·   API   ·   FAQ   ·   Solana   ·   974 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 27ms · UTC 22:15 · PVG 06:15 · LAX 14:15 · JFK 17:15
    ♥ Do have faith in what you're doing.