1.1 进程虚拟地址空间划分
任何的编程语言 =》产生两种东西:指令和数据。
在磁盘上的xxx.exe文件,运行时,加载到内存中,但不是直接加载到物理内存。
x86 32位Linux环境下:
全局(or局部静态)初始化非0变量存放在.data(数据块),全局(or局部静态)初始化为0和未初始化的变量存放在.bss块;
局部变量不产生符号,只生成指令,存放在.text(指令块);
int gdata1 = 10; //程序运行后,存放在.data
int gdata2 = 0; //存放在.bss
int gdata3; //存放在.bss
static int gdata4 = 11; //存放在.data
static int gdata5 = 0; //存放在.bss
static int gdata6; //存放在.bss
int main(){
int a = 1; //生成指令 mov dword ptr[ebp-4],0x1 ,存放在.text
int b = 0; //存放在.text
int c; //存放在.text
static int d = 2; //存放在.data
static int e = 0; //存放在.bss
static int f; //存放在.bss
return 0;
}
1.2 函数调用栈详细过程
问题一:main函数调用sum,sum执行完以后,如何知道回到哪个函数中?
问题二:sum函数执行完,回到main函数以后,怎么知道从哪一行指令继续执行?
int sum(int a,int b){
int temp = 0;
temp = a + b;
return temp;
} // ret
int main(){
int a = 10;
int b = 20;
int ret = sum(a,b); // call sum
cout << ret << endl;
return 0;
}
一个程序从main函数开始运行,main函数会开辟堆栈空间,其中ebp存放栈底地址,esp存放栈顶地址。
call指令调用sum函数时,会先将下一条指令的地址先入栈,sum函数开辟一片自己的栈空间,并将ebp入栈,esp指向新开辟的栈的栈顶,执行完之后的ret指令会将ebp出栈,存放在cpu的PC寄存器里,返回main函数,随即执行下一条指令。