C/C++函数传参,汇编分析
本帖最后由 冬冬 于 2012-3-26 21:33 编辑函数传参介绍:_cdecl这是C/C++采用的默认的传参方式,即参数按从右到左依次入栈。且有调用者负责清理堆栈.
1、EBP寄存器,栈基址寄存器。
这本是一个通用寄存器,但在长期的编程习惯中,人们给了它一个默认的约定,通常用来堆栈传参后,执行call后的栈指针值。
2、我利用内联汇编分析了:
#include <iostream>
using namespace std;
int Add(int a,int b)
{
int tmp_A,tmp_B;
int tmp_EBP;
__asm
{
push eax
mov eax,
mov tmp_A,eax
mov eax,
mov tmp_B,eax
mov tmp_EBP,ebp
pop eax
}
cout<<"EBP+0:\t\t"<<hex<<uppercase<<tmp_EBP<<endl;
cout<<"EBP+4\t\t"<<hex<<*(int*)(tmp_EBP+4)<<endl;
cout<<"EBP+8\t\t"<<hex<<*(int*)(tmp_EBP+8)<<endl;
cout<<"EBP+12\t\t"<<hex<<*(int*)(tmp_EBP+12)<<endl<<endl;
cout<<"第一个参数\t"<<hex<<tmp_A<<endl;
cout<<"第二个参数\t"<<hex<<tmp_B<<endl;
return tmp_A+tmp_B;
}
int main()
{
Add(123,456);
return 0;
}
//输出结果:
EBP: 2DFD40 //那么这几个值是啥呢???
EBP+0: 2DFE1C //那么这几个值是啥呢???
EBP+4 131193A //那么这几个值是啥呢???
EBP+8 7B //毫无疑问,这是我要传递的参数
EBP+12 1C8 //毫无疑问,这是我要传递的参数
第一个参数 7B
第二个参数 1C8
请按任意键继续. . .
我们在VC++中进入调试模式,查看反汇编代码(ALT+8)
先来看下Main函数内:
int main()
{
01311910push ebp
01311911mov ebp,esp
01311913sub esp,0C0h
01311919push ebx
0131191Apush esi
0131191Bpush edi
0131191Clea edi,
01311922mov ecx,30h
01311927mov eax,0CCCCCCCCh
0131192Crep stos dword ptr es:
Add(123,456);
0131192Epush 1C8h
01311933push 7Bh
01311935call Add (13110B4h)
0131193Aadd esp,8 //注意下他的指令地址与 输出EBP+4 131193A
system("Pause");
0131193Dmov esi,esp
0131193Fpush offset string "Pause" (13178B8h)
01311944call dword ptr
0131194Aadd esp,4
0131194Dcmp esi,esp
0131194Fcall @ILT+445(__RTC_CheckEsp) (13111C2h)
return 0;
01311954xor eax,eax
}
//看看他们的指令地址:
01311935call Add (13110B4h)
0131193Aadd esp,8 //注意下他的指令地址与 输出EBP+4 131193A
知道ESP+4是啥了不?
4、EBP和EBP+4的值什么。
EBP: 2DFD40 //那么这几个值是啥呢???
EBP+0: 2DFE1C //那么这几个值是啥呢???
介绍下OEP即入口地址:
C语言每个函数的开头均已
push ebp // EBP寄存器保护
mov ebp,esp
而函数结束
mov esp,ebp //回复ESP寄存器,以保持对战平衡
pop ebp //函数入口时的esp寄存器既然回复了,我们利用esp寄存器,就可以回复ebp寄存器了。
至于我在函数中,输出的EBP和EBP+0 值我想聪明的你应该知道是啥了。
呵呵至此,分析完毕......
我至于初学者,许多地方也是凭着才想去实验的.....
遗留的几个问题解答:
push ebp // EBP寄存器保护
mov ebp,esp
那么EBP的值自然是 进入call之后的ESP值。
第二个问题:【EBP+0】
是进入call执
pushebp
那么 EBP+0就是 上次EBP的值,入栈一边保护寄存器用
本帖最后由 libocdf 于 2012-3-26 14:04 编辑
难得的好帖。楼主,这个应该置顶加精。。不过问题的关键点是EBP和EBP+0的值,但仔细看源程序中,只有对EBP+0的输出,而没有EBP的输出 本来想加分的。。结果我没有贡献值。。擦擦擦!! 文章还有其他一些问题。比如楼主提出的问题“知道ESP+4是啥了不?”应该是想问“EBP+4”或“ESP-0ch”吧。。就是call压入的返回地址。还有“4、EBP和EBP+4的值什么。”应该是“4、EBP和EBP+0的值什么。”吧。。这里我确实没看懂。。。望楼主解答一下。 libocdf 发表于 2012-3-26 14:19 static/image/common/back.gif
文章还有其他一些问题。比如楼主提出的问题“知道ESP+4是啥了不?”应该是想问“EBP+4”或“ESP-0ch”吧。。 ...
push ebp // EBP寄存器保护
mov ebp,esp
那么EBP的值自然是 进入call之后的ESP值。
第二个问题:【EBP+0】
是进入call执
pushebp
那么 EBP+0就是 上次EBP的值,入栈一边保护寄存器用 完全不明白,小菜呀,努力学习,超越楼主 不懂得汇编,看不明白 真是难得给力的帖子啊。 强烈支持楼主ing…… 好贴,只不过看着头晕啊啊
肿么办!!!~?
真是难得给力的帖子啊。 C语言,C++,真没易语言好学 楼主加油,鱼C加油!我们都看好你哦! 好,谢谢分享 给力!!!!!!!!!!!!!!!! 楼主,函数的传递不保证从右至左,每个c++编绎器不一样 不错的啊:lol: 表示不是很懂 看不懂{:10_277:},难受啊
页:
[1]