函數如何調用,在hello world中已經研究過
現在看看一個例子,如何在不傳遞參數的情況下,對變量進行操作
首先對一個c小代碼進行彙編研究
#include <iostream>
using namespace std;
void print()
{
}
int main()
{
int s=1;
int ss=2;
print();
return 0;
}
利用vs2008觀察彙編代碼:
int main()
{
01361480 push ebp
01361481 mov ebp,esp
01361483 sub esp,0D8h
01361489 push ebx
0136148A push esi
0136148B push edi
0136148C lea edi,[ebp-0D8h]
01361492 mov ecx,36h
01361497 mov eax,0CCCCCCCCh
0136149C rep stos dword ptr es:[edi]
<strong> int s=1;
0136149E mov dword ptr [s],1
int ss=2;
013614A5 mov dword ptr [ss],2 </strong>
print();
013614AC call print (13610AFh)
return 0;
013614B1 xor eax,eax
}
void print()
{
<strong>013613C0 push ebp
013613C1 mov ebp,esp </strong>
013613C3 sub esp,0C0h
013613C9 push ebx
013613CA push esi
013613CB push edi
013613CC lea edi,[ebp-0C0h]
013613D2 mov ecx,30h
013613D7 mov eax,0CCCCCCCCh
013613DC rep stos dword ptr es:[edi]
}
這裡需要了解一個概念,寄存器EBP,
書本了解就是
擴充 基址 指針 寄存器(extended base pointer) 其記憶體放一個指針,該指針指向系統棧最上面一個 棧幀的底部。 簡單而言就是,在函數嵌套調用時,當一個函數傳回時,如何保證還要回到之前的棧位址,就需要EBP這個寄存器,
在進如print時,可以看到頭兩句彙編,就是将上一個函數的棧底壓棧,儲存現場,
如果得到這個棧底位址就可以操作變量了
oid print()
{
unsigned int addr;
__asm{
mov addr,ebp
}
int *p=(int *)(*(int *)addr-8);
cout<<*p<<endl;
}
看看vs單步調試的一些資訊
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsIiclRnblN0LclHdpZXYyd2LcBzNvwVZ2x2bzNXak9CX90TQNNkRrFlQKBTSvwFbslmZvwFMwQzLcVmepNHdu9mZvwFVywUNMZTY18CX052bm9CX90TQPlXTq1EMRRUT4FEVkZXUYpVd1kmYr50MZV3YyI2cKJDT29GRjBjUIF2LcRHelR3LcJzLctmch1mclRXY39jN4gDN1EDN1EDNxQDM1EDMy8CX0Vmbu4GZzNmLn9Gbi1yZtl2Lc9CX6MHc0RHaiojIsJye.jpg)
再看看print函數中師傅捕獲到這個EBP
通過這樣應該明白這種方法的原理了