Chinaunix首页 | 论坛 | 博客
  • 博客访问: 684492
  • 博文数量: 85
  • 博客积分: 1797
  • 博客等级: 上尉
  • 技术积分: 1238
  • 用 户 组: 普通用户
  • 注册时间: 2007-12-02 08:53
个人简介

职位:技术总监 1、精通c++(linux平台、vc++Mfc、qt)、java、php、unity3d,略懂python 2、用c++开发过嵌入式产品,用c++开发过大型银行运维产品 3、用java开发大型银行运维产品,学校教务系统 4、用php开发进销存系统(在销售中),用php开发淘宝小程序 5、用unity3d开发衣柜设计软件,在运营中

文章分类

全部博文(85)

分类: 嵌入式

2011-09-21 21:45:35

函数参数入栈分析以及带参数的汇编函数的写法

随便找个函数调用,看看调用函数时,编译器做了什么。
看看uc/os在vc实现的代码,调试时,同时打开汇编功能,可以看到下面情况

  1. 63: OSTaskCreate(TaskStart, 0, &TaskStk[0][TASK_STK_SIZE-1], TaskStart_Prio);
  2. 004162D7 push 1
  3. 004162D9 push offset _TaskStk+1FFCh (0044609c)
  4. 004162DE push 0
  5. 004162E0 push offset @ILT+860(_TaskStart) (00401361)
  6. 004162E5 call @ILT+40(_OSTaskCreate) (0040102d)
  7. 004162EA add esp,10h

从汇编可以看出,程序调用OSTaskCreate函数时所做的事情,四个push操作,分别对应四个参数,从右到左。
关于这一句004162E5   call        @ILT+40(_OSTaskCreate) (0040102d) 可以看看这几个链接的解释


call指令同时将ip压入栈。

进入OSTaskCreate函数后,要把那几个参数找出来。但栈存的不只是那四个参数,因此不能用pop指令,可以使用ebp,来找到参数取

出,先看看刚进入函数,编译器所做的操作

  1. 156: INT8U OSTaskCreate (void (*task)(void *pd), void *pdata, OS_STK *ptos, INT8U prio)
  2. 157: {
  3. 00406F20 push ebp
  4. 00406F21 mov ebp,esp
  5. 00406F23 sub esp,48h
  6. 00406F26 push ebx
  7. 00406F27 push esi
  8. 00406F28 push edi
  9. 00406F29 lea edi,[ebp-48h]
  10. 00406F2C mov ecx,12h
  11. 00406F31 mov eax,0CCCCCCCCh
  12. 00406F36 rep stos dword ptr [edi]

这只是保存了要用到寄存器的信息,并没有找到那几个参数。实际上再向后看,当用到这些参数时,才将参数从栈中取出
00406F38   mov         eax,dword ptr [ebp+14h]             ;取prio
00406F87   mov         eax,dword ptr [ebp+10h]             ;取ptos
00406F8B   mov         ecx,dword ptr [ebp+0Ch]             ;pdata
00406F8F   mov         edx,dword ptr [ebp+8]               ;task
这就是四个参数的取出方式。

所以我们写自己的带参数汇编函数时,就可以仿照上面来写,先保存ebp,几个寄存器,再取参数。
下面这段汇编就是这样实现的 取自《自己动手写操作系统》。

  1. ; ------------------------------------------------------------------------
  2. ; 内存拷贝,仿 memcpy
  3. ; ------------------------------------------------------------------------
  4. ; void* MemCpy(void* es:pDest, void* ds:pSrc, int iSize);
  5. ; ------------------------------------------------------------------------
  6. MemCpy:
  7. push ebp
  8. mov ebp, esp

  9. push esi
  10. push edi
  11. push ecx

  12. mov edi, [ebp + 8] ; es:pDest
  13. mov esi, [ebp + 12] ; ds:pSrc
  14. mov ecx, [ebp + 16] ; iSize
阅读(5549) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~