当前位置: 首页 > 知识库问答 >
问题:

可变大小堆栈框架的程序集(关于局部变量的堆栈)

苏胤
2023-03-14
long vframe(long n, long idx, long *q){
    long i;
    long *p[n];
    p[0] = &i;
    for(i=1; i<n; i++)
        p[i]=q;
    return *p[idx];
}

我有vframe函数并生成了如下的汇编代码

1: vframe:
2:    pushq    %rbp
3:    movq     %rsp, %rbp
4:    subq     $16, %rsp
5:    leaq     22(, %rdi, 8), %rax      # I think the number 22 is vary from machine and OS
6:    andq     $-16, %rax       
7:    subq     %rax, %rsp
8:    leaq     7(%rsp), %rax
9:    shrq     $3, %rax
10:   leaq     0(, %rax, 8), %r8
11:   movq     %r8, %rcx
................................
12: L3:
13:   movq     %rdx, (%rcx, %rax, 8)
14:   addq     $1, %rax
15:   movq     %rax, -8(%rbp)
16: L2:
17:   movq     -8(%rbp), %rax
18:   cmpq     %rdi, %rax
19:   jl       L3
20:   leave
21:   ret

如果我们看到从8到11行,我们没有在堆栈上推送p的地址,但汇编已经假设

如果我们希望某些参数不被破坏,我们会推送一些寄存器并将被调用者保存的寄存器移动到推送的寄存器。但是,在这种情况下,似乎不是。关于局部变量还有其他约定吗,比如i和

共有1个答案

商飞翮
2023-03-14

编译器在内部跟踪每个局部变量的偏移量,包括p。它不需要将局部变量的地址存储在堆栈上。在这种情况下,它知道p在(%rsp)。

此代码不使用除rbp之外的任何调用保留寄存器,因此这是它保存的唯一寄存器。

 类似资料:
  • 我试过下面的程序。创建此程序的目的是了解有关堆栈大小的更多信息。 执行上述代码后,由于堆栈大小分配过大,程序崩溃。堆栈的最大可能大小是多少?是否为每个程序/计算机固定?可以增加吗? 我想知道是为了知识。如果有人能提供C/C中的例子,那将是非常有帮助的。

  • 我对Java没什么概念。 我浏览了一些链接,发现博客上写着“存储在堆栈上的Java原语”,我觉得这取决于实例变量或局部变量。 经过几个环节,我的结论是, 类变量(原语)作为对象的一部分存储在堆中。 类变量——对象(用户定义)——作为对象的一部分存储在堆中。这对于参考对象和实际对象都是正确的。 方法变量——基元——作为堆栈框架的一部分存储在堆栈上。 方法变量-对象(用户定义)-存储在堆上,但是对堆上

  • 问题内容: 我对Java不太了解。 我浏览了几个链接,发现博客上写着“ Java Primitives存储在堆栈上”,我觉得这取决于实例变量或局部变量。 经过几个链接后,我的结论是, 类变量(基元)作为对象包含的对象的一部分存储在堆中。 类变量– object(用户定义)–作为其包含的Object的一部分存储在堆中。对于参考对象和实际对象都是如此。 方法变量-基元-作为该堆栈框架的一部分存储在堆栈

  • 根据以下链接,java堆栈框架包含本地变量、操作数堆栈和当前类常量池引用。http://blog.jamesdbloom.com/JVMInternals.html 同样来自Oracle“JVM结构”第2.6节。3.“动态链接-每个帧(§2.6)包含对当前方法类型的运行时常量池(§2.5.5)的引用,以支持方法代码的动态链接。” 我还读到堆中的对象也有一个指向类数据的指针/引用。https://w

  • 问题内容: 当我在Intellij Idea中调试Java应用程序时,我在堆栈框架中看到所有变量,如下所示: “ @”后面的数字是什么意思?它不同于hashCode返回的内容。hashCode以十六进制表示形式返回数字2a134eca,等于整数表示形式705908426。数字77和705908426是不同的。 问题答案: @是自应用程序启动以来的对象计数编号。因此,@ 1012表示自应用启动以来创

  • 以下是完整的问题: 编写一个java方法,它将接受两个排序后的堆栈a和B(最小值在顶部),并返回一个排序后的堆栈D(最小值在顶部)。只允许使用堆栈操作,如pop、push、isEmpty和peek。 示例:假设A={(top)1,4,7,9}和B={(top)2,3,6},那么函数将返回一个新的堆栈D={(top)1,2,3,4,6,7,9} 我写的代码是这样的: 你怎么认为?