首页
社区
课程
招聘
[原创]关于子函数参数与堆栈的学习笔记
发表于: 2008-11-2 15:48 9688

[原创]关于子函数参数与堆栈的学习笔记

2008-11-2 15:48
9688

【文章标题】: 关于子函数参数与堆栈的学习笔记
【文章作者】: eASYCODe
【作者主页】: http://blog.sina.com.cn/77muyulong
【作者声明】: 菜菜学习中的一点点收获,错误请诸大侠指正…
--------------------------------------------------------------------------------
【详细过程】
  玩着玩着RA3 突然电脑重启 好扫兴 于是决定用玩的精力来记录最近学到的一点东西 故撰写此文…
  
  我一边做一边写 所以有的时候也许看起来逻辑很混乱 包涵哈 仅是笔记罢了~
  
  上个星期在拜读了N篇有关于PEDIY的教程之后终于决定自己下手了 选的是某个小游戏的特典包 打算给它添加几个快捷键
  注入自己写的DLL 但是发现在调用时有些问题 程序会出错退出 故而认真学习了有关于子函数参数与堆栈的内容 自
  以为受益匪浅
  首先要说明的是 这个笔记中所说的程序代码分别是C ASM和分汇编 对比进行 应该更有说服力
  
  先来看这样一个程序
  
  C代码
  

  int Fanc(int a,int b,int c)
  {
  int d,e,f;
  d=a;
  e=a+b;
  f=a+b+c;
  return f;
  }
  
  
  main()
  {
  int x=1,y=2,z=3,m;
  m=Fanc(x,y,z);
  
  }
  ;C反汇编代码
  
  ;main()
  ;{
  00401088                 |.  C745 FC 01000000 mov dword ptr ss:[ebp-4],1
  0040108F                 |.  C745 F8 02000000 mov dword ptr ss:[ebp-8],2
  00401096                 |.  C745 F4 03000000 mov dword ptr ss:[ebp-C],3
  0040109D                 |.  8B45 F4          mov eax,dword ptr ss:[ebp-C]
  004010A0                 |.  50               push eax
  004010A1                 |.  8B4D F8          mov ecx,dword ptr ss:[ebp-8]
  004010A4                 |.  51               push ecx
  004010A5                 |.  8B55 FC          mov edx,dword ptr ss:[ebp-4]
  004010A8                 |.  52               push edx
  004010A9                 |.  E8 57FFFFFF      call proj.00401005                ;Fanc()
  ;{
 
  00401005                     $ /E9 16000000        jmp proj.00401020
 
  
  
  00401020                 /> \55               push ebp
  00401021                 |.  8BEC             mov ebp,esp
  00401023                 |.  83EC 4C          sub esp,4C
  00401026                 |.  53               push ebx
  00401027                 |.  56               push esi
  00401028                 |.  57               push edi
  00401029                 |.  8D7D B4          lea edi,dword ptr ss:[ebp-4C]
  0040102C                 |.  B9 13000000      mov ecx,13
  00401031                 |.  B8 CCCCCCCC      mov eax,CCCCCCCC
  00401036                 |.  F3:AB            rep stos dword ptr es:[edi]
  00401038                 |.  8B45 08          mov eax,dword ptr ss:[ebp+8]
  0040103B                 |.  8945 FC          mov dword ptr ss:[ebp-4],eax
  0040103E                 |.  8B4D 08          mov ecx,dword ptr ss:[ebp+8]
  00401041                 |.  034D 0C          add ecx,dword ptr ss:[ebp+C]
  00401044                 |.  894D F8          mov dword ptr ss:[ebp-8],ecx
  00401047                 |.  8B55 08          mov edx,dword ptr ss:[ebp+8]
  0040104A                 |.  0355 0C          add edx,dword ptr ss:[ebp+C]
  0040104D                 |.  0355 10          add edx,dword ptr ss:[ebp+10]
  00401050                 |.  8955 F4          mov dword ptr ss:[ebp-C],edx
  00401053                 |.  8B45 F4          mov eax,dword ptr ss:[ebp-C]
  00401056                 |.  5F               pop edi
  00401057                 |.  5E               pop esi
  00401058                 |.  5B               pop ebx
  00401059                 |.  8BE5             mov esp,ebp
  0040105B                 |.  5D               pop ebp
  0040105C                 \.  C3               retn
  
  
  ;}
  004010AE                 |.  83C4 0C          add esp,0C
  004010B1                 |.  8945 F0          mov dword ptr ss:[ebp-10],eax
 
  
.386
.model flat,stdcall
option casemap:none
include Windows.inc
include kernel32.inc 
includelib kernel32.lib
.data
x  dw  1
y  dw  2
z  dw  3
.data?
m  dd  ?
.code 
start:
    push 0
    call GetCommandLine
    push eax
    push 0
    invoke GetModuleHandle, NULL
    push eax
    call WinMain
    invoke ExitProcess, eax
Fanc proc ma:DWORD,mb:DWORD,mc:DWORD 
  
  LOCAL d
  LOCAL e
  LOCAL f
  mov ecx,ma
  mov d,ecx
  add ecx,mb
  mov e,ecx
  add ecx,mc
  mov f,ecx
  mov eax,f
  ret
 
Fanc endp
WinMain PROC hInst:DWORD, hInstPrev:DWORD, szCmdLine:DWORD, nCmdShow:DWORD
push z
push y
push x
call Fanc
mov m,eax
ret
WinMain ENDP
end start

[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

收藏
免费 7
支持
分享
最新回复 (11)
雪    币: 251
活跃值: (25)
能力值: ( LV9,RANK:290 )
在线值:
发帖
回帖
粉丝
2
下面的文章对这个问题也讲得很好
Win32环境下函数调用的堆栈之研究(http://bbs.pediy.com/showthread.php?t=69909
2008-11-2 16:04
0
雪    币: 709
活跃值: (2420)
能力值: ( LV12,RANK:1010 )
在线值:
发帖
回帖
粉丝
3
学习~~~
2008-11-2 17:27
0
雪    币: 2067
活跃值: (82)
能力值: ( LV9,RANK:180 )
在线值:
发帖
回帖
粉丝
4
学习再学习.
2008-11-2 20:44
0
雪    币: 186
活跃值: (26)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
有一个细节问题问一下啊,为何调用子函数处:

  004010A9                 |.  E8 57FFFFFF      call proj.00401005                ;Fanc()
  ;{
  
  
是这样,而下面列出的子函数的首地址是0x00401020??
2008-11-2 21:13
0
雪    币: 264
活跃值: (11)
能力值: ( LV9,RANK:250 )
在线值:
发帖
回帖
粉丝
6
已经把代码补上了 那里是个跳转 是所有函数的索引~
2008-11-8 03:59
0
雪    币: 1708
活跃值: (586)
能力值: ( LV15,RANK:670 )
在线值:
发帖
回帖
粉丝
7
除了学习,还要让更多的人看见这个帖子~!
2008-11-8 09:10
0
雪    币: 167
活跃值: (1574)
能力值: ( LV9,RANK:250 )
在线值:
发帖
回帖
粉丝
8
自己动手 丰衣足食 :-)
2008-11-8 09:12
0
雪    币: 479
活跃值: (25)
能力值: ( LV8,RANK:130 )
在线值:
发帖
回帖
粉丝
9
楼主这段稍微要注意一个问题;__fastcall调用约定有些差别,在于函数的第一、二个DWORD类型参数(或者类型长度更小的参数)通过寄存器ecx和edx传递,其余参数通过栈来传递,从右向左压栈,由被调用者负责栈的平衡。
2008-11-8 18:01
0
雪    币: 264
活跃值: (11)
能力值: ( LV9,RANK:250 )
在线值:
发帖
回帖
粉丝
10
受教~感谢指点…
2008-11-8 18:47
0
雪    币: 738
活跃值: (476)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
11
楼主写得很好!很清楚得说明问题
2008-11-8 21:54
0
雪    币: 231
活跃值: (45)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
qdk
12
x86体系CPU的通用寄存器少,所以只能这么干
2008-11-9 04:33
0
游客
登录 | 注册 方可回帖
返回
//