好像理解出现一点儿偏差了,一直以为: 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
注意:两个没有测试代码中计算相对地址的减法刚好相反。
1
共 2 条评论, 1 页
评论区
写评论感觉是,编译器不小心帮你优化了一下
这样就正常了
据说这种问题mir有奇效
真实情况我也不知道了