CSAPP--第三章中函数调用与返回的细节

来源:互联网 发布:uml类图用什么软件 编辑:程序博客网 时间:2024/06/09 14:45

对于以下操作:

void fun(){    int x = 1;    return;}int main(){    int y = 2;    fun();}

vs2015Pro生成汇编码部分如下,结合其来弄清楚函数调用与返回过程中寄存器与内存具体发生了什么

01211208  jmp         fun (01211700h)  void fun(){01211700  push        ebp  01211701  mov         ebp,esp  01211703  sub         esp,0CCh  01211709  push        ebx  0121170A  push        esi  0121170B  push        edi  0121170C  lea         edi,[ebp-0CCh]  01211712  mov         ecx,33h  01211717  mov         eax,0CCCCCCCCh  0121171C  rep stos    dword ptr es:[edi]      int x = 1;0121171E  mov         dword ptr [x],1      return;}01211725  pop         edi  01211726  pop         esi  01211727  pop         ebx  01211728  mov         esp,ebp  0121172A  pop         ebp  0121172B  ret  int main(){0121174A  push        esi  0121174B  push        edi  0121174C  lea         edi,[ebp-0CCh]  01211752  mov         ecx,33h  01211757  mov         eax,0CCCCCCCCh  0121175C  rep stos    dword ptr es:[edi]      int y = 2;0121175E  mov         dword ptr [y],2      fun();01211765  call        fun (01211208h)  }0121176A  xor         eax,eax  0121176C  pop         edi  0121176D  pop         esi  0121176E  pop         ebx  0121176F  add         esp,0CCh

从指令call开始说起:

01211765 call fun (01211208h)
执行前之前
ebp 0x00AFFC90–帧指针
eip 0x01211765–计数器
esp 0x00AFFBB8–栈指针
内存:
0x00AFFBB4 8b 0e 8c b1 ?.??
0x00AFFBB8 46 10 21 01 F.!.

执行之后(相当于将下一条指令入栈,并且计数器跳转到相应的fun()的地址)
ebp 0x00AFFC90–帧指针
eip 0x01211208–计数器(01211208 jmp fun (01211700h) 这条指令)
esp 0x00AFFBB8–栈指针
并且内存变为
0x00AFFBB4 6a 17 21 01 j.!.这里是小端机,读出为 0121176A 恰为main函数中call后下一条指令地址
0x00AFFBB8 46 10 21 01 F.!.

之后01211700 push ebp
将帧指针入栈
内存:
0x00AFFBB0 90 fc af 00 ???.
0x00AFFBB4 6a 17 21 01 j.!.
0x00AFFBB8 46 10 21 01 F.!.

之后01211701 mov ebp,esp
将帧指针入栈的地址作为新的帧指针地址
ebp 0x00AFFBB0–帧指针(恰为存放main帧指针的地址)
eip 0x01211703–计数器
esp 0x00AFFBB8–栈指针

然后
01211703 sub esp,0CCh
预分配栈空间或者是用作保护(?这里有点不确定)
ebp 0x00AFFBB0–帧指针
eip 0x01211709–计数器
esp 0x00AFFAE4–栈指针

执行一段时间fun()后
0121171C rep stos dword ptr es:[edi]
似乎是在进行栈的保护工作
将不停地在内存中从小到大(即像退栈pop一样)不停地将内存中区域置为cc cc cc cc,直到帧指针处

最后
0121172A pop ebp
0121172B ret
弹出ebp,跳回main函数

从整个过程还可以看出:

我经过多次编译,main()函数与fun()函数的地址是一样的
但是每次分配的内存是不同的
想到现代计算机为了防止黑客入侵–在消息中插入可执行代码–这一机制导致的随机分配内存?

0 0
原创粉丝点击