|
本帖最后由 gmh5225 于 2014-12-25 14:47 编辑
写这个纯属就是自己记录下自己的学习经历,没有其他的意思。
C函数的传递方式有三种: (1) __cdecl (2) __stacall (3) __fastcall 当然还有其他的 pascal register 什么的,不过这都不是C调用的,不管
先随便写下三种方式的函数
- int __cdecl add1(int a,int b)
- {
- return a+b;
- }
- int __stdcall add2(int a,int b)
- {
- return a+b;
- }
- int __fastcall add3(int a,int b)
- {
- return a+b;
- }
- int main()
- {
- int a=3,b=4,c=0;
- c=add1(a,b);
- c=add2(a,b);
- c=add3(a,b);
- printf("%d",c);
- system("pause");
- return 0;
- }
复制代码
载入OD- 003C1040 > 55 push ebp ;保存原来ebp指针
- 003C1041 8BEC mov ebp, esp ; ebp指向esp,即堆栈
- 003C1043 83EC 0C sub esp, 0xC ; 开辟12个字节空间供3个变量
- 003C1046 C745 FC 0300000>mov dword ptr [ebp-0x4], 0x3 ; int a
- 003C104D C745 F8 0400000>mov dword ptr [ebp-0x8], 0x4 ; int b
- 003C1054 C745 F4 0000000>mov dword ptr [ebp-0xC], 0x0 ; int c
- 003C105B 8B45 F8 mov eax, dword ptr [ebp-0x8]
- 003C105E 50 push eax ; 压 b
- 003C105F 8B4D FC mov ecx, dword ptr [ebp-0x4]
- 003C1062 51 push ecx ; 压 b
- 003C1063 E8 98FFFFFF call testtest.add1 ; _cdecl调用
- 003C1068 83C4 08 add esp, 0x8 ; 在函数外部平衡堆栈
- 003C106B 8945 F4 mov dword ptr [ebp-0xC], eax
- 003C106E 8B55 F8 mov edx, dword ptr [ebp-0x8]
- 003C1071 52 push edx ; 压 b
- 003C1072 8B45 FC mov eax, dword ptr [ebp-0x4]
- 003C1075 50 push eax ; 压 a
- 003C1076 E8 95FFFFFF call testtest.add2 ; _stdcall 在函数内部平衡堆栈
- 003C107B 8945 F4 mov dword ptr [ebp-0xC], eax
- 003C107E 8B55 F8 mov edx, dword ptr [ebp-0x8] ; _fastcall特色 不压参数
- 003C1081 8B4D FC mov ecx, dword ptr [ebp-0x4] ; 分别传递b,a
- 003C1084 E8 97FFFFFF call testtest.add3
- 003C1089 8945 F4 mov dword ptr [ebp-0xC], eax
- 003C108C 8B4D F4 mov ecx, dword ptr [ebp-0xC]
- 003C108F 51 push ecx
- 003C1090 68 F4203C00 push testtest.003C20F4 ; ASCII "%d"
- 003C1095 FF15 9C203C00 call dword ptr [<&MSVCR100.printf>] ; msvcr100.printf
- 003C109B 83C4 08 add esp, 0x8
- 003C109E 68 F8203C00 push testtest.003C20F8 ; ASCII "pause"
- 003C10A3 FF15 A4203C00 call dword ptr [<&MSVCR100.system>] ; msvcr100.system
- 003C10A9 83C4 04 add esp, 0x4
- 003C10AC 33C0 xor eax, eax ;清空eax
- 003C10AE 8BE5 mov esp, ebp ;esp指向当前ebp,同步跟进
- 003C10B0 5D pop ebp ; 还原原来ebp指针
- 003C10B1 C3 retn
复制代码
__cdecl函数内部
- 003C1000 > 55 push ebp
- 003C1001 8BEC mov ebp, esp
- 003C1003 8B45 08 mov eax, dword ptr [ebp+0x8] //这里是第一个参数,也就是a
- 003C1006 0345 0C add eax, dword ptr [ebp+0xC] // b
- 003C1009 5D pop ebp
- 003C100A C3 retn
复制代码 __stdcall函数内部
- 003C1010 > 55 push ebp
- 003C1011 8BEC mov ebp, esp
- 003C1013 8B45 08 mov eax, dword ptr [ebp+0x8] //一样,第一个参数 ,a
- 003C1016 0345 0C add eax, dword ptr [ebp+0xC] // b
- 003C1019 5D pop ebp
- 003C101A C2 0800 retn 0x8 //这里就是上述所说的在函数内部的堆栈平衡
复制代码 __fastcall函数内部
- 003C1020 > 55 push ebp
- 003C1021 8BEC mov ebp, esp
- 003C1023 83EC 08 sub esp, 0x8 //开辟8个字节,也就是2个int的空间
- 003C1026 8955 F8 mov dword ptr [ebp-0x8], edx //此edx就是函数外部的ebx ,也就是b
- 003C1029 894D FC mov dword ptr [ebp-0x4], ecx //这是a
- 003C102C 8B45 FC mov eax, dword ptr [ebp-0x4] //a赋值给eax
- 003C102F 0345 F8 add eax, dword ptr [ebp-0x8] //eax=eax+b
- 003C1032 8BE5 mov esp, ebp
- 003C1034 5D pop ebp
- 003C1035 C3 retn <font color="#0000ff">//因为之前没有压栈,这里不需要平衡
复制代码 总结一下:_cdecl 和_stdcall 传递参数需要压栈,_cdecl和_fastcall在函数内部返回时不需要平衡堆栈,并且_cdecl在函数外部平衡堆栈,_fastcall因为根本就没有压栈,所以不需要平衡堆栈,最后是_stdcall是在函数内部返时平衡的堆栈 , 前2种满足堆栈的压栈方式,先进后出,也就是第一个压入的变量其实是最后一个。
这里要纠正一个错误:__fastcall 前2个int 都是由ecx和edx传递的,多余的函数还是需要和上面2个调用函数一样,需要压栈
补例:- 0020107E 8B4D F4 mov ecx, dword ptr [ebp-0xC] ; 这里函数原型是int add(int a,int b,int c) 超过了2个int,所以需要压栈
- 00201081 51 push ecx ; //压入c
- 00201082 8B55 F8 mov edx, dword ptr [ebp-0x8] //传递b
- 00201085 8B4D FC mov ecx, dword ptr [ebp-0x4] //传递 a
- 00201088 E8 93FFFFFF call testtest.add3
复制代码
汇编命令自行百度谷歌。。。别来问我了
|
评分
-
参与人数 41 | HB +71 |
THX +27 |
收起
理由
|
动动
| |
+ 1 |
|
猫妖的故事
| |
+ 1 |
|
花盗睡鼠
| + 2 |
+ 1 |
[吾爱汇编论坛52HB.COM]-学破解防破解,知进攻懂防守! |
24567
| + 2 |
+ 1 |
[吾爱汇编论坛52HB.COM]-学破解防破解,知进攻懂防守! |
Jawon
| + 2 |
|
|
sjtkxy
| + 1 |
+ 1 |
|
一路走来不容易
| + 1 |
|
|
虚心学习
| + 1 |
|
|
Soul1999
| + 1 |
|
|
冷亦飞
| + 1 |
|
|
消逝的过去
| |
+ 1 |
|
车太震
| + 1 |
|
[吾爱汇编论坛52HB.COM]-感谢楼主热心分享,小小评分不成敬意! |
小菜虫
| + 1 |
|
[吾爱汇编论坛52HB.COM]-感谢楼主热心分享,小小评分不成敬意! |
liugu0hai
| + 1 |
+ 1 |
[吾爱汇编论坛52HB.COM]-感谢楼主热心分享,小小评分不成敬意! |
涡流忍者
| + 1 |
|
[吾爱汇编论坛52HB.COM]-软件反汇编逆向分析,软件安全必不可少! |
ldljlzw
| + 1 |
|
|
weiran324
| + 1 |
|
[吾爱汇编论坛52HB.COM]-吃水不忘打井人,给个评分懂感恩! |
叶落花开
| + 2 |
|
[吾爱汇编论坛52HB.COM]-软件反汇编逆向分析,软件安全必不可少! |
jaunic
| + 2 |
|
|
bnjzzheng
| |
+ 1 |
[吾爱汇编论坛52HB.COM]-吃水不忘打井人,给个评分懂感恩! |
hnymsh
| |
+ 1 |
|
lies
| + 1 |
|
|
轻轻不语
| + 3 |
+ 1 |
评分=感恩!简单却充满爱!感谢您的作品! |
nuojiya8
| + 1 |
|
★★★★★ 热心人,佛祖保佑你事事顺利 ,财源滚滚!!! |
Top丶邪少
| + 5 |
+ 1 |
评分=感恩!简单却充满爱!感谢您的作品! |
am873
| + 2 |
+ 1 |
评分=感恩!简单却充满爱!感谢您的作品! |
小梦
| + 1 |
+ 1 |
评分=感恩!简单却充满爱!感谢您的作品! |
sndncel
| + 2 |
+ 1 |
评分=感恩!简单却充满爱!感谢您的作品! |
雨季
| + 3 |
+ 1 |
评分=感恩!简单却充满爱!感谢您的作品!!. |
若只如初见
| + 2 |
+ 1 |
★★★★★ 热心人,佛祖保佑你事事顺利 ,财源滚滚!!! |
阿菜
| + 2 |
+ 1 |
论坛有你更精彩!感谢楼主! |
Scar-疤痕
| + 4 |
+ 1 |
好人有好报!你的热心我永远不忘!谢谢! |
水寒
| + 1 |
+ 1 |
好人有好报!你的热心我永远不忘!谢谢! |
逍遥枷锁
| + 2 |
+ 1 |
★★★★★ 热心人,佛祖保佑你事事顺利 ,财源滚滚!!! |
jolly_800
| + 1 |
+ 1 |
教程非常易懂,对新人帮助极大!楼主大爱! |
十月
| + 1 |
+ 1 |
★★★★★ 热心人,佛祖保佑你事事顺利 ,财源滚滚!!! |
Mrsin
| + 2 |
+ 1 |
评分=感恩!简单却充满爱!感谢您的作品! |
小者
| + 2 |
+ 1 |
评分=感恩!简单却充满爱!感谢您的作品! |
Desire
| + 3 |
+ 1 |
评分=感恩!简单却充满爱!感谢您的作品! |
520Kelly
| + 2 |
+ 1 |
评分=感恩!简单却充满爱!感谢您的作品!!. |
Shark恒
| + 10 |
+ 1 |
感谢分享学习笔记,赞一个~ |
查看全部评分
|