一、奇怪的汉字是怎么产生的呢?
当我们上网查询的时候,我们会发现网上用了一句简单的话来概括:
在VC 的debug模式下,在栈中新分配的内存会初始化为 0xcc,在堆中新分配的内存会初始化为 0xcd,这时打印出来分别对应烫和屯,我们来下面一个代码来验证一下这个现象。
#include<stdio.h>
#include<Windows.h>
//这里这个代码主要是想表示一下栈帧开辟的时候初始化的空间
//从而引入函数栈帧开辟的关系
int main()
{int a[10];int i = 0;while(1){printf("%c", a[i]);i++;Sleep(1000);}return 0;
}
//栈帧销毁
我们会发现这样一个现象:
二、我们来看一下函数创建栈帧的过程
我们写一个简单的函数,然后用main函数去进行调用:
int MyAdd(int a,int b)
{int c = a + b;return c;
}int main()
{int x = 0xA;int y = 0xB;int z = MyAdd(x, y);printf("z=%x\n", z);return 0;
}
按住F10启动调试,然后打开调试->窗口->堆栈和寄存器。然后我们开始运行程序,转到反汇编里面,发现在调用main函数之前,编译器还帮我们执行了一系列操作,
根据上面的现象,我们可以的到一下一个结论的内存图。
我们观察寄存器,首先先来认识一下寄存器,常见的寄存器
eax:通常用于保存临时数据,常用return保存返回值
ebx:通用寄存器,常用于保存临时数据
ebp:栈底寄存器、esp:栈顶寄存器、eip:指令寄存器,保存下一条指令的地址
mov:数据转移指令,
push:数据入栈,esp的位置发生改变
pop:数据弹出到指定位置,同时esp栈顶寄存器的位置要发生改变
sub:减法
add:加法
call:函数调用,压入返回地址,转入目标函数
jump:通过修改eip,转入目标函数,进行调用
ret:恢复返回地址,压入eip,类似pop eip命令
销毁的过程就是弹出栈,返回给操作系统内存。