#include
int NUM=100;
int n;
static int m= 36;
int sum(int _a,int _b)
{
int c=0;
c=_a+_b;
return c;
}
int main()
{
int a=10;
int b=20;
int c ;
printf("%p",&c);
printf("%p",&NUM);
int ret=sum(a,b);
return 0;
}
我们发现一个问题,就是全局变量 NUM 和局部变量 cc 和c 的内存地址差距比较大,不是同一段代码吗,真么差距这么大呢
那我们就进入计算机内部看看
gdb main
1
这样我们就进来了首先我们简单设置一下,我们的cpu 是x86 架构,设置一下汇编格式
set disassembly-flavor intel
1
我们想看看代码,看看选择在哪里打断点
l(gdb) l
4
5 int n;
6
7 static int m= 36;
8 int sum(int _a,int _b)
9 {
10 int c=0;
11 c=_a+_b;
12 printf("c的地址是 %p\n",&c);
13 return c;
(gdb) l
14 }
15
16
17 int main()
18 {
19
20 int a=10;
21 int b=20;
22
23 int cc ;
(gdb) l
24
25 printf("cc的地址是 %p\n",&cc);
26 printf("NUM的地址是 %p\n",&NUM);
27 int ret=sum(a,b);
28 return 0;
29 }
(gdb) l
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
打断点
b 10
1
b 20
1
b 21
1
b 27
1
开始运行
r
1
我们可以看到运行到了第20行,这下我们要停下来仔细看看
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
Breakpoint 2, main () at main.c:20
20 int a=10;
1
2
3
4
5
info frame
1
我们看到 frame 在0x7fffffffdbb0, 我们看到 rip = 0x5555555551eb,在文章开头我们说过 全局变量 NUM 和局部变量 cc 和c 的内存地址差距比较大 也是 cc的地址是 0x7ffe45591048 NUM的地址是 0x55c8cffb9010
当前的栈帧 位置是 在0x7fffffffdbb0
(gdb) info frame
Stack level 0, frame at 0x7fffffffdbb0:
rip =0x5555555551eb in main(main.c:20); saved rip =0x7ffff7da8d90
source language c.
Arglist at 0x7fffffffdba0, args:
Locals at 0x7fffffffdba0, Previous frame's sp is 0x7fffffffdbb0
Saved registers:
rbp at 0x7fffffffdba0, rip at 0x7fffffffdba8
1
2
3
4
5
6
7
8
9
我们继续运行
n
1
info frame
1
当前的栈帧 位置是 frame at 0x7fffffffdbb0,发现栈帧没有变
(gdb) n
Breakpoint 3, main () at main.c:21
21 int b=20;
(gdb) info frame
Stack level 0, frame at 0x7fffffffdbb0:
rip = 0x5555555551f2 in main (main.c:21); saved rip = 0x7ffff7da8d90
source language c.
Arglist at 0x7fffffffdba0, args:
Locals at 0x7fffffffdba0, Previous frame's sp is 0x7fffffffdbb0
Saved registers:
rbp at 0x7fffffffdba0, rip at 0x7fffffffdba8
1
2
3
4
5
6
7
8
9
10
11
12
13
我们继续运行 0x7fffffffdbb0 还是没有变
(gdb) n
25 printf("cc的地址是 %p\n",&cc);
(gdb) info frame
Stack level 0, frame at 0x7fffffffdbb0:
rip = 0x5555555551f9 in main (main.c:25); saved rip = 0x7ffff7da8d90
source language c.
Arglist at 0x7fffffffdba0, args:
Locals at 0x7fffffffdba0, Previous frame's sp is 0x7fffffffdbb0
Saved registers:
rbp at 0x7fffffffdba0, rip at 0x7fffffffdba8
1
2
3
4
5
6
7
8
9
10
11
查看局部变量的地址,我们发现 a,b ,cc 的位置是彼此挨着的
$12 = (int *) 0x7fffffffdb8c
(gdb) p &a
$13 = (int *) 0x7fffffffdb8c
(gdb) p &b
$14 = (int *) 0x7fffffffdb90
(gdb) p &cc
$15 = (int *) 0x7fffffffdb88
1
2
3
4
5
6
7
还是没有变frame at 0x7fffffffdbb0,在调用子函数 sum 之前 都没有变
(gdb) n
NUM的地址是 0x555555558010
Breakpoint 4, main () at main.c:27
27 int ret=sum(a,b);
(gdb) info frame
Stack level 0, frame at 0x7fffffffdbb0:
rip = 0x555555555232 in main (main.c:27); saved rip = 0x7ffff7da8d90
source language c.
Arglist at 0x7fffffffdba0, args:
Locals at 0x7fffffffdba0, Previous frame's sp is 0x7fffffffdbb0
Saved registers:
rbp at 0x7fffffffdba0, rip at 0x7fffffffdba8
1
2
3
4
5
6
7
8
9
10
11
12
13
14
继续运行
n
info frame
1
2
我们 现在靠近了 int ret=sum(a,b); 但是我们还在main 函数中 frame at 0x7fffffffdbb0 没有变,好了小心了
(gdb) n
NUM的地址是 0x555555558010
Breakpoint 4, main () at main.c:27
27 int ret=sum(a,b);
(gdb) info frame
Stack level 0, frame at 0x7fffffffdbb0:
rip = 0x555555555232 in main (main.c:27); saved rip = 0x7ffff7da8d90
source language c.
Arglist at 0x7fffffffdba0, args:
Locals at 0x7fffffffdba0, Previous frame's sp is 0x7fffffffdbb0
Saved registers:
rbp at 0x7fffffffdba0, rip at 0x7fffffffdba8
1
2
3
4
5
6
7
8
9
10
11
12
13
n
info frame
1
2
(gdb) n
Breakpoint 1, sum (_a=10, _b=20) at main.c:10
10 int c=0;
(gdb) info frame
Stack level 0, frame at 0x7fffffffdb80:
rip = 0x55555555518a in sum (main.c:10); saved rip = 0x555555555241
called by frame at 0x7fffffffdbb0
source language c.
Arglist at 0x7fffffffdb70, args: _a=10, _b=20
Locals at 0x7fffffffdb70, Previous frame's sp is 0x7fffffffdb80
Saved registers:
rbp at 0x7fffffffdb70, rip at 0x7fffffffdb78
1
2
3
4
5
6
7
8
9
10
11
12
13
我们发现 frame 的函数地址变了 从 frame at 0x7fffffffdbb0 变成了frame at 0x7fffffffdb80
再重复一遍,我们发现 frame 的地址变了 从 frame at 0x7fffffffdbb0 变成了frame at 0x7fffffffdb80,从main 中到 sum 中
再重复一遍,0x7fffffffdbb0到0x7fffffffdb80 是减小的,我的意思是,sum函数的frame 在 main 的下面,在低地址位置
==========
|| main || 高地址位置 -------->0x7fffffffdbb0
|| sum || 低地址位置 -------->0x7fffffffdb80