我们直接用linux演示
我们将这个代码编译成目标文件,然后查看内容
#include <stdlib.h> #include <pthread.h> int sum(int x,int y) { return x+y; } int main(){ sum(2,3); return 0; }
编译
我们反汇编这个目标文件
我们发现这些汇编代码不好阅读,其实这里是因为 这个文件还没有link(链接)
注:c语言执行过程:程序的编译、链接和执行
我们link这个文件
我们可以看到两个函数的入口
这里其实是内存的虚地址
objdump -d p
这里有个公式:物理地址:基址+逻辑地址(虚地址)
如果这里基址为1000,那么main函数的物理入口地址为1000+1141
内存空间示例
这里是示例不一定为实际参数
内核指令在内核空间内,程序执行所在的空间是用户空间
我们用objdump 查看的就是text代码段的内容
堆和栈需要运行时才可以看到
我们这里可以查看下data段的数据
我们写一个有静态变量的进程
int global_var = 5; int main(){ static int static_var = 6; return 0; }
我们编译(不是link)
objdump -s -d p1.o
我们注意一下上面的.text
大家可以看到规律了吧,其实上面的就是一串一串的机器指令串
我们在写一个程序,来观察堆和栈
#include <stdlib.h> #include <unistd.h> #include <stdio.h> int global_var = 5; int main(){ static int static_var = 6; int local_var = 7; int*p = (int*)malloc(100);//Be careful: %lx我的Ubuntu系统报错,我用%p输出 printf("the global_var address is %p\n", &global_var); printf("the static_var address is %p\n", &static_var); printf("the local_var address is %p\n", &local_var); printf("the address which the p points to %p\n", p); free(p); sleep(1000); //We need watch the process state, so let it sleep deeply. return 0; }
记录一下ps -e的进程地址
我们看下进程的状态
看下进程的map
我们可以观察前面的代码输出
the global_var address is 0x559827164010 the static_var address is 0x559827164014 the local_var address is 0x7ffdf146573c the address which the p points to 0x559828e642a0
第一、二个全局变量对应这一行的区间,证明这里是data区域
第三个局部变量对应这一行的区间
第四个申请的堆的空间