從匯編的角度去理解函數(shù)會(huì)讓你更加的深刻盗温。熔酷。。当娱。吃既。。
看這篇文章需要一定的c語(yǔ)言基礎(chǔ)和匯編基礎(chǔ)(能基本看懂簡(jiǎn)單的匯編指令)
先來(lái)分析一個(gè)簡(jiǎn)單的函數(shù)
這個(gè)函數(shù)功能是將兩個(gè)數(shù)相加并返回結(jié)果
當(dāng)我們這樣調(diào)用
這是它的匯編代碼
這是add函數(shù)的匯編代碼 其他的匯編代碼不用管
00401078 push 8 //第二個(gè)參數(shù)的值
0040107A push 7 //第一個(gè)參數(shù)的值
0040107C call @ILT+20(add) (00401019)
00401081 add esp,8
根據(jù)上面這段匯編代碼我們得知
調(diào)用add函數(shù)的代碼趾访,參數(shù)是這樣傳遞的:
先分別把兩個(gè)參數(shù)的值給傳入棧中(一般都是自右向左的傳入?yún)?shù))
當(dāng)call指令執(zhí)行時(shí) 自動(dòng)將call的下一條指令的地址(函數(shù)返回地址)傳入棧中
然后跳到00401019這個(gè)地址
我們進(jìn)這個(gè)call來(lái)看看
這個(gè)jmp只是用來(lái)作為中轉(zhuǎn)的
繼續(xù)執(zhí)行
好 進(jìn)來(lái)了
這個(gè)就是add函數(shù)的匯編代碼
我們來(lái)分析這段匯編代碼
//將ebp寄存器也就是棧底保存到棧中
push ebp
//ebp用來(lái)尋找椞恚空間地址 為了方便esp更好的操作棧空間
mov ebp,esp
//開辟內(nèi)存大小為40h(注意是十六機(jī)制6笮)的椛暧悖空間
sub esp,40h
//這三個(gè)寄存器要拿來(lái)當(dāng)指針操作
所以需要先保存,
程序返回時(shí)需要恢復(fù)云头,以免數(shù)據(jù)被破壞
push ebx //[ebp-4]
push esi //[ebp-8]
push edi //[ebp-0xC]
//填充椌栌眩空間
lea edi,[ebp-40h] //將棧頂?shù)牡刂方oedi
mov ecx,10h
mov eax,0CCCCCCCCh
//將eax的值放入edi的內(nèi)存空間(棧)中 執(zhí)行ecx次 每執(zhí)行一次edi+4
//大致意思就是把棧空間全部填為CC
rep stos dword ptr [edi]
//這里是這個(gè)函數(shù)的主要功能
mov eax,dword ptr [ebp+8] //ebp+8存的就是我們第一個(gè)參數(shù)的值
add eax,dword ptr [ebp+0Ch] //ebp+0ch存的第二個(gè)參數(shù)的值
//恢復(fù)堆棧
pop edi
pop esi
pop ebx
//恢復(fù)棧頂
mov esp,ebp
//恢復(fù)棧底
pop ebp
//函數(shù)返回
//就是把eip寄存器的值
修改成函數(shù)返回地址(eip存的地址就是CPU下一條執(zhí)行的指令)
ret
這樣分析函數(shù)已經(jīng)夠詳細(xì)了吧
如果還看不懂可能是基礎(chǔ)不夠
可以自己觀察椑;保空間的數(shù)值變化 很有趣的匣砖!