< 返回版块

xie-jirong 发表于 2020-07-12 09:43

Tags:调用栈 内存布局

好像理解出现一点儿偏差了,一直以为: 1, 调用栈的分配地址是从高往低走, 2, 调用函数时,先参数入栈,再返回地址入栈,然后,发生调用, 3, 入栈调用参数时,最后一个先入、最后是第一个参数, 4, 被调用函数的新局部变量,在栈的最新位置(即地址最低区域)布置。

fn addr<T: Sized>(obj: &T) -> isize {
    obj as *const T as isize
}

fn main() {
    let i1 = 23_i64;
    let i2 = 34_i64;
    let base = addr(&i1);
    println!("local addr {}, {}, {}",
             addr(&i1)-base, addr(&i2)-base, addr(&base)-base);
    func1(base, i1, 2);
}

fn func1(base: isize, arg: i64, n: i64) {
    let n2 = n -1;
    println!("level {}, addr {} {} {} {}", n,
             addr(&base)-base, addr(&arg)-base, addr(&n)-base, addr(&n2)-base);
    if n2 > 0 {
        func1(base, arg, n2);
    }
}

运行输出:

local addr 0, 8, 16
level 2, addr -392 -384 -376 -360
level 1, addr -856 -848 -840 -824

说明, 1, 栈是从高往低走, 2, 入栈参数是最后先入, 但是,局部变量却位于比 参数更旧的区域? 而且,在局部变量中,先申明的没有在更前面的地方(大地址),先申明,应该作用域更大,如果考虑作用域嵌套,应应该是后申明(子作用域)在栈顶(低地址)还可以在一个函数调用中实现空间的重复利用啊?

C语言测试,也是这样。

#include <stdio.h>
#include <inttypes.h>

size_t addr(int64_t*p) {
  return (size_t) p;
}

void func1(size_t base, int64_t arg, int64_t n) {
  int64_t n2 = n-1;
  printf("level %ld, addr %ld, %ld, %ld, %ld\n",
         n, base-addr(&base), base-addr(&arg), base-addr(&n), base-addr(&n2));
  if ( n2 > 0 ) {
    func1(base, arg, n2);
  }
}

int main() {
  int64_t i1 = 23;
  int64_t i2 = 34;
  size_t base = addr(&i1);
  printf("local addr %ld, %ld, %ld\n",
         base-addr(&i1), base-addr(&i2), base-addr(&base));
  func1(base, i1, 2);
  return 0;
}

输出:

local addr 0, -8, -16
level 2, addr 72, 80, 88, 64
level 1, addr 168, 176, 184, 160

注意:两个没有测试代码中计算相对地址的减法刚好相反。

评论区

写评论
Neutron3529 2020-07-12 20:02

感觉是,编译器不小心帮你优化了一下

fn func1(base: it, arg: it, n: it){
    println!("level {}, addr {} {} {}", n, addr!(&base)-base, addr!(&arg)-base, addr!(&n)-base);
    let n2 = n +1;
    println!("level {}, addr {} {} {} {}", n, addr!(&base)-base, addr!(&arg)-base, addr!(&n)-base, addr!(&n2)-base);
    if n2 < 0 {
        func1(base, arg, n2)
    }
}

这样就正常了

Neutron3529 2020-07-12 12:26

据说这种问题mir有奇效

真实情况我也不知道了

1 共 2 条评论, 1 页