分析函数调用的汇编指令
生活随笔
收集整理的這篇文章主要介紹了
分析函数调用的汇编指令
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
同樣一段c++代碼生成的匯編指令可能會不一樣。有多種原因,例如編譯器、調用約定或者底層平臺。
今天要分析的是cdecl在x86機器上用visual c++ 2005上的編譯結果。
首先需要設置一下項目配置以得到從源代碼生成的匯編代碼。
項目屬性->配置屬性->c/c++->輸出文件->匯編輸出 = Assembly With Source Code (/FAs)。
要被編譯的源文件是:
Code#include?"stdafx.h"
struct?Point3D
{
????int?X;
????int?Y;
????int?Z;
????Point3D(int?x,?int?y,?int?z):X(x),Y(y),Z(z)
????{}
};
Point3D?AddPoint3D(Point3D?p1,?Point3D?p2)
{
????Point3D?p(p1);
????p.X?+=?p2.X;
????p.Y?+=?p2.Y;
????p.Z?+=?p2.Z;
????return?p;
}
void?main()
{
????Point3D?p1(1,2,3);
????Point3D?p2(4,5,6);
????Point3D?p3?=?AddPoint3D(p1,p2);
}
?
生成的匯編代碼是:
?
Code;?Listing?generated?by?Microsoft?(R)?Optimizing?Compiler?Version?14.00.50727.762?
????TITLE????d:\project\CheckAsm\CheckAsm\CheckAsm.cpp
????.686P
????.XMM
????include?listing.inc
????.model????flat
INCLUDELIB?MSVCRTD
INCLUDELIB?OLDNAMES
PUBLIC?????AddPoint3D@@YA?AUPoint3D@@U1@0@Z????????;?AddPoint3D
EXTRN????@_RTC_CheckStackVars@8:PROC
EXTRN????__RTC_Shutdown:PROC
EXTRN????__RTC_InitBase:PROC
;????COMDAT?rtc$TMZ
;?File?d:\project\checkasm\checkasm\checkasm.cpp
rtc$TMZ????SEGMENT
__RTC_Shutdown.rtc$TMZ?DD?FLAT:__RTC_Shutdown
rtc$TMZ????ENDS
;????COMDAT?rtc$IMZ
rtc$IMZ????SEGMENT
__RTC_InitBase.rtc$IMZ?DD?FLAT:__RTC_InitBase
;?Function?compile?flags:?/Odtp?/RTCsu?/ZI
rtc$IMZ????ENDS
;????COMDAT??AddPoint3D@@YA?AUPoint3D@@U1@0@Z
;上面一堆先不管
_TEXT????SEGMENT;定義PE文件中的Text段
_p$?=?-16????????????????????????;?size?=?12;
___$ReturnUdt$?=?8????????????????????;?size?=?4
_p1$?=?12????????????????????????;?size?=?12
_p2$?=?24????????????????????????;?size?=?12
;上面4個符號是AddPoint3D這個方法中的局部變量、返回值和參數的偏移量(相對于ebp)
?AddPoint3D@@YA?AUPoint3D@@U1@0@Z?PROC????????????;?AddPoint3D,?COMDAT?AddPoint3D方法的定義開始,由于name?mangling,名稱變為了AddPoint3D@@YA?AUPoint3D@@U1@0@Z
;?15???:?{
????push????ebp;保存caller的ebp到堆棧
????mov????ebp,?esp;設置本方法的ebp。ebp在方法調用的開始階段被設置,結束階段被還原,調用過程中保持不變。ebp表示為本次調用所分配的堆棧楨的起始地址
????sub????esp,?212????????????????;?000000d4H?esp減少一定的數量,表示為本次調用在棧上分配了一定的空間。讓我們把>ebp?&&?<=?現在的esp?的這段內存稱之為locals
????push????ebx;保存現場的3個push
????push????esi
????push????edi
????lea????edi,?DWORD?PTR?[ebp-212];把edi設置成剛才sub?esp后esp的值,也就是locals的最低地址
????mov????ecx,?53????????????????????;?00000035H?53?*?4?=?212,?you?see?whats?going?on?here?
????mov????eax,?-858993460????????????????;?ccccccccH????設置eax=cccccccch
????rep?stosd?;這是一個串操作指令,其意義是
;while(ecx)
;{
;????*(int*)edi?=?eax;
;????edi?+=?sizeof(int);//這里就是4
;????ecx--;
;}
;本指令和它上面的三條指令完成了把locals這段內存初始化成一片ccccccccccccccccccccc.
;當此指令執行完畢,edi?==?ebp
;?16???:?????Point3D?p(p1);
????mov????eax,?DWORD?PTR?_p1$[ebp]
????mov????DWORD?PTR?_p$[ebp],?eax
????mov????ecx,?DWORD?PTR?_p1$[ebp+4]
????mov????DWORD?PTR?_p$[ebp+4],?ecx
????mov????edx,?DWORD?PTR?_p1$[ebp+8]
????mov????DWORD?PTR?_p$[ebp+8],?edx
;復制構造局部變量p。_p1$[ebp]的意思就是[ebp?+?_p1$],_p1$是在前面定義過的一個偏移量
;?17???:?????p.X?+=?p2.X;
????mov????eax,?DWORD?PTR?_p$[ebp]
????add????eax,?DWORD?PTR?_p2$[ebp]
????mov????DWORD?PTR?_p$[ebp],?eax
;?18???:?????p.Y?+=?p2.Y;
????mov????eax,?DWORD?PTR?_p$[ebp+4]
????add????eax,?DWORD?PTR?_p2$[ebp+4]
????mov????DWORD?PTR?_p$[ebp+4],?eax
;?19???:?????p.Z?+=?p2.Z;
????mov????eax,?DWORD?PTR?_p$[ebp+8]
????add????eax,?DWORD?PTR?_p2$[ebp+8]
????mov????DWORD?PTR?_p$[ebp+8],?eax
;這些很好理解
;?20???:?
;?21???:?????return?p;
????mov????eax,?DWORD?PTR?___$ReturnUdt$[ebp]
;ReturnUdt中的Udt表示user?defined?type
;這條指令的意思是,調用方在從ebp開始偏移量是___$ReturnUdt$的dword中保存的返回值應當存放的地址,把這個地址加載到eax中
;此時eax保存的是一個地址,這個地址實際上call中局部變量p3的地址
????mov????ecx,?DWORD?PTR?_p$[ebp]
????mov????DWORD?PTR?[eax],?ecx
????mov????edx,?DWORD?PTR?_p$[ebp+4]
????mov????DWORD?PTR?[eax+4],?edx
????mov????ecx,?DWORD?PTR?_p$[ebp+8]
????mov????DWORD?PTR?[eax+8],?ecx
;從局部變量p復制到call的局部變量p3中
????mov????eax,?DWORD?PTR?___$ReturnUdt$[ebp]
;在eax中保存返回值的地址
;?22???:?}
;這一段{
????push????edx
????mov????ecx,?ebp
????push????eax
????lea????edx,?DWORD?PTR?$LN5@AddPoint3D
????call????@_RTC_CheckStackVars@8
????pop????eax
????pop????edx
;這一段}可以忽略掉,并不是我們程序邏輯的一部分
????pop????edi
????pop????esi
????pop????ebx
????mov????esp,?ebp
????pop????ebp
????ret????0;函數返回,返回值的保存地址存放在eax中
????npad????2
$LN5@AddPoint3D:
????DD????1
????DD????$LN4@AddPoint3D
$LN4@AddPoint3D:
????DD????-16????????????????????;?fffffff0H
????DD????12????????????????????;?0000000cH
????DD????$LN3@AddPoint3D
$LN3@AddPoint3D:
????DB????112????????????????????;?00000070H
????DB????0
?AddPoint3D@@YA?AUPoint3D@@U1@0@Z?ENDP????????????;?AddPoint3D
_TEXT????ENDS
PUBLIC??????0Point3D@@QAE@HHH@Z????????????????;?Point3D::Point3D
PUBLIC????_main
EXTRN????__RTC_CheckEsp:PROC
;?Function?compile?flags:?/Odtp?/RTCsu?/ZI
;????COMDAT?_main
_TEXT????SEGMENT
_p3$?=?-56????????????????????????;?size?=?12
_p2$?=?-36????????????????????????;?size?=?12
_p1$?=?-16????????????????????????;?size?=?12
_main????PROC????????????????????????;?COMDAT
;?25???:?{
;主函數的調用過程
;參見上面的注釋{
????push????ebp
????mov????ebp,?esp
????sub????esp,?252????????????????;?000000fcH
????push????ebx
????push????esi
????push????edi
????lea????edi,?DWORD?PTR?[ebp-252]
????mov????ecx,?63????????????????????;?0000003fH
????mov????eax,?-858993460????????????????;?ccccccccH
????rep?stosd
;參見上面的注釋}
;?26???:?????Point3D?p1(1,2,3);
????push????3
????push????2
????push????1
????lea????ecx,?DWORD?PTR?_p1$[ebp];ecx傳遞this指針,thiscall
????call??????0Point3D@@QAE@HHH@Z????????????;?Point3D::Point3D
;?27???:?????Point3D?p2(4,5,6);
????push????6
????push????5
????push????4
????lea????ecx,?DWORD?PTR?_p2$[ebp]
????call??????0Point3D@@QAE@HHH@Z????????????;?Point3D::Point3D
;?28???:?????Point3D?p3?=?AddPoint3D(p1,p2);
????sub????esp,?12????????????????????;?0000000cH?分配實參p1的空間并按值傳遞
????mov????eax,?esp
????mov????ecx,?DWORD?PTR?_p2$[ebp]
????mov????DWORD?PTR?[eax],?ecx
????mov????edx,?DWORD?PTR?_p2$[ebp+4]
????mov????DWORD?PTR?[eax+4],?edx
????mov????ecx,?DWORD?PTR?_p2$[ebp+8]
????mov????DWORD?PTR?[eax+8],?ecx
????sub????esp,?12????????????????????;?0000000cH?分配實參p2的空間并按值傳遞
????mov????edx,?esp
????mov????eax,?DWORD?PTR?_p1$[ebp]
????mov????DWORD?PTR?[edx],?eax
????mov????ecx,?DWORD?PTR?_p1$[ebp+4]
????mov????DWORD?PTR?[edx+4],?ecx
????mov????eax,?DWORD?PTR?_p1$[ebp+8]
????mov????DWORD?PTR?[edx+8],?eax
????lea????ecx,?DWORD?PTR?_p3$[ebp]
????push????ecx????;注意這個地方,p3的地址被保存在這里,也就是返回值的地址
????call?????AddPoint3D@@YA?AUPoint3D@@U1@0@Z????;?AddPoint3D
????add????esp,?28????????????????????;?0000001cH?調用方清理參數堆棧28=12+12+4
;?29???:?}
????xor????eax,?eax
????push????edx
????mov????ecx,?ebp
????push????eax
????lea????edx,?DWORD?PTR?$LN7@main
????call????@_RTC_CheckStackVars@8
????pop????eax
????pop????edx
????pop????edi
????pop????esi
????pop????ebx
????add????esp,?252????????????????;?000000fcH
????cmp????ebp,?esp
????call????__RTC_CheckEsp
????mov????esp,?ebp
????pop????ebp
????ret????0
????npad????3
$LN7@main:
????DD????3
????DD????$LN6@main
$LN6@main:
????DD????-16????????????????????;?fffffff0H
????DD????12????????????????????;?0000000cH
????DD????$LN3@main
????DD????-36????????????????????;?ffffffdcH
????DD????12????????????????????;?0000000cH
????DD????$LN4@main
????DD????-56????????????????????;?ffffffc8H
????DD????12????????????????????;?0000000cH
????DD????$LN5@main
$LN5@main:
????DB????112????????????????????;?00000070H
????DB????51????????????????????;?00000033H
????DB????0
$LN4@main:
????DB????112????????????????????;?00000070H
????DB????50????????????????????;?00000032H
????DB????0
$LN3@main:
????DB????112????????????????????;?00000070H
????DB????49????????????????????;?00000031H
????DB????0
_main????ENDP
;?Function?compile?flags:?/Odtp?/RTCsu?/ZI
_TEXT????ENDS
;????COMDAT???0Point3D@@QAE@HHH@Z
_TEXT????SEGMENT
_this$?=?-8????????????????????????;?size?=?4
_x$?=?8????????????????????????????;?size?=?4
_y$?=?12????????????????????????;?size?=?4
_z$?=?16????????????????????????;?size?=?4
??0Point3D@@QAE@HHH@Z?PROC????????????????;?Point3D::Point3D,?COMDAT
;?_this$?=?ecx
;?11???:?????{}
????push????ebp
????mov????ebp,?esp
????sub????esp,?204????????????????;?000000ccH
????push????ebx
????push????esi
????push????edi
????push????ecx
????lea????edi,?DWORD?PTR?[ebp-204]
????mov????ecx,?51????????????????????;?00000033H
????mov????eax,?-858993460????????????????;?ccccccccH
????rep?stosd
????pop????ecx
????mov????DWORD?PTR?_this$[ebp],?ecx
????mov????eax,?DWORD?PTR?_this$[ebp]
????mov????ecx,?DWORD?PTR?_x$[ebp]
????mov????DWORD?PTR?[eax],?ecx
????mov????eax,?DWORD?PTR?_this$[ebp]
????mov????ecx,?DWORD?PTR?_y$[ebp]
????mov????DWORD?PTR?[eax+4],?ecx
????mov????eax,?DWORD?PTR?_this$[ebp]
????mov????ecx,?DWORD?PTR?_z$[ebp]
????mov????DWORD?PTR?[eax+8],?ecx
????mov????eax,?DWORD?PTR?_this$[ebp]
????pop????edi
????pop????esi
????pop????ebx
????mov????esp,?ebp
????pop????ebp
????ret????12????????????????????;?0000000cH
??0Point3D@@QAE@HHH@Z?ENDP????????????????;?Point3D::Point3D
_TEXT????ENDS
END
That's it.
轉載于:https://www.cnblogs.com/zhy2002/archive/2008/12/10/1351796.html
總結
以上是生活随笔為你收集整理的分析函数调用的汇编指令的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 开发ASP.NET Atlas服务器端E
- 下一篇: redis 的雪崩和穿透?