[32位汇编系列]003 汇编中__stdcall 调用约定以及参数传递

看了上一篇文章[32位汇编系列]002 - 创建标准的windows窗口(3) 之后, 你是否对反汇编代码中有很多ebp+xxx 或者ebp-xxx之类的指令感觉很疑惑, 今天, 我还以 上一篇文章的例子 中的窗口过程_WinProc的反汇编代码作为例子, 来详细的说明一下在32位汇编中, 参数以及局部变量是如何被程序使用的。

 

首先你必须明白一个事实是, Windows的绝大部分api都是以__stdcall方式调用的, 之所以说绝大部分, 是因为有个别的api因为要用到不定参数, 所以, 采用了c/c++的__cdecl 调用约定。 如果你对什么是函数的调用约定不甚了解,那么我建议你先看看这篇文章:调用方式__cdecl和__stdcall的异同点

 

接着, 我们要详细的讨论一下这段代码【_WinProc的反汇编代码】:

 

00401000  /.  55                  push    ebp
00401001  |.  8BEC              mov     ebp, esp
00401003  |.  83C4 AC         add     esp, -54

 

上面这段代码, 是一个汇编的过程的经典代码,在子程序进行任何操作之前, 先保存2个重要的寄存器ebp和esp

通过push ebp 将ebp的值先压入栈中, 接着把当前esp的值赋值给ebp, 以后就可以通过操作ebp来访问各个

参数以及局部变量了, add esp, -54 , 这个是为局部变量保存空间, 这里申请了有3个局部变量:

    local    @stPS:PAINTSTRUCT
    local    @stRC:RECT
    local    @hDC

 

前面2个是结构PAINTSTRUCT和结构RECT, 后面一个是DWORD类型的变量

你不妨计算一下, 这三个局部变量所占用空间的大小

sizeof(PAINTSTRUCT) + sizeof(RECT) + sizeof(DWORD) = 64 + 16 + 4 = 84

这里是10进制, 换成16进制就是0x54 ,这就是为什么要用add esp, -54

需要注意的是, 这里所有的反汇编代码中出现的数字都是16进制的。

经过上面的分析, 我们来看看具体的栈空间示意图:

 

|..................|         低地址

----------------

|   ebp-54    |         hDC的地址 <--当前esp值

----------------

|   ebp-50    |        @stRC:RECT首地址

|-------------- |

|   ebp-4C    | 

----------------

|   ebp-48    |

----------------

|   ebp-44    |

----------------

|    ebp-40   |       @stPS:PAINTSTRUCT   首地址

----------------

|    ..........     |

-----------------

|    ebp         |     进入子程序, ebp被压入栈中

-----------------

|    ebp+4     |     子程序返回地址

-----------------

|    ebp+8     |     参数hWnd

-----------------

|    ebp+C     |     参数uMsg

-----------------

|     ebp+10  |     参数wParam

-----------------

|     ebp+14  |    参数lParam

------------------

|    ...........    |       高地址

 

从栈空间示意图可以清晰的看出, 进入子程序之前, 由调用程序把4个参数从右到做依次压入栈中

接着通过call指令把子程序_WinProc的返回地址也压入栈中

进入子程序后, 首先ebp被压入栈中, 接着为3个局部变量分配0x54个字节的局部空间

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值