内存布局与堆栈调用
/内存布局/
程序的内存布局
kemel space内核
stack栈
dynamic libraries动态加在空间
heap堆
read/write sections数据段.bss.data
readonly sections代码段.text .only read data
reserved预定段
栈/
1.相关汇编指令含义
汇编指令:首先汇编指令基本还原了cpu执行方式,cpu只认地址。
mov把,右边的值(地址中的值)放在左边的地址中。word两字节dword四字节;
mov dword ptr [ebp-4],0Ah----把10放到ebp-4这个4字节内存地址中(0Ah中h代表常量数字0A就是16进制的10)
这里面的dword ptr代表从内存里取值的意思。
push如栈
sub esp,44h esp-=44h
lea是移地址
lea edi,[ebp-44h];
mov ecx,11h
mov eax,0cccccccch
rep stos dword ptr[edi]
//这里rep stos循环拷贝语句拷贝次数是第一句拷贝值是第二句拷贝地点是第三局
add eax,dword ptr[ebp+0ch] add+=
//这里就是把ebp+12这个地址的值+到eax中
pop ebp//这就是出栈,并将值付给ebp
unix汇编从左向右看 x86从右向左看。
临时变量属于指令,栈访问一律采用ebp偏移量来访问。
c++采用从右向左压,是因为为了实现可变参函数,要遍历一下整个参数列表才能确定压多少参数。
2.调用过程(类似汇编):
进入函数前准备:
(1)压参数:mov ebx dword ptr[ebp-4];push ebx;
(2)压main下一行指令地址: call sum(任意函数);
(3)压ebp地址ebp被esp赋值:push ebp;mov ebp esp;
(4)开辟0xcccccc:sub esp,44h(不确定数字)lea edi,[ebp-44h];mov ecx,11h;mov eax,0CCCCCh;rep stos dword ptr[edi];
(这里要强调一下(2)中使用mov而(4)中不能用mov只能用lea,汇编指令中mov的右值如果为一个[]表达式那么mov会自动取表达式结果的
地址的值,我们通常使用lea解决这个问题取得表达式的地址)。
函数功能完成后:
(1)返回值传递:mov eax dword ptr [ebp-4];
(2)回退ebp:mov esp,ebp;pop ebp; (完成后esp指向下一指令地址的储存空间上)
(3)给pc寄存器下一行指令地址并让esp再次回退到压入参数处:ret
(4)形参栈针esp回退(回退在主调方函数内经行(这个要看调用约定));
3调用约定(调用约定加在函数名前面即可使用)
_cdecl c调用约定
_stdcall windows标准调用约定(例如如上他的汇编有ret 8,形参由被调用方回退)
_fastcall 快速调用约定(例如如上他的汇编里面形参那里就没有push ebx,ebx直接作为存储容器)
_thiscall c++的成员函数调用约定
调用约定带来的不同:
1函数产生符号名不同
2函数参数入栈顺序
3谁来清理形参内存
/堆/
相关书籍:深入理解计算机系统第九章
malloc free
malloc小于128k使用sbrk,大于使用mmap--都会产生内存碎片。