汇编-__fastcall前两个参数的堆栈问题

发布于 2016-11-17 12:12:39 字数 706 浏览 1279 评论 1

查看微软内部函数的时候用的是fastcall调用,前两个参数不被放到堆栈中传入,而是放入 ecx和edx 中。ecx 中将保存第一个参数,edx 中保存第二个。而取参数的形式如:

mov eax,dword ptr [ebp+8] ;取第一个参数

kd> u IoGetDeviceAttachmentBaseRef
nt!IoGetDeviceAttachmentBaseRef:
8081cb3e 8bff mov edi,edi
8081cb40 55 push ebp
8081cb41 8bec mov ebp,esp
8081cb43 53 push ebx
8081cb44 56 push esi
8081cb45 ff1508118080 call dword ptr [nt+0x1108 (80801108)]
8081cb4b ff7508 push dword ptr [ebp+8]
8081cb4e 8ad8 mov bl,al

WinDBG查询一个函数时也发现有将[ebp+8]压入堆栈的行为,push dword ptr [ebp+8]的作用?
取第一个参数时为什么用ebp+8 ?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

想挽留 2017-01-26 12:53:08

是把IoGetDeviceAttachmentBaseRef的第一个参数传给IopGetDeviceAttachmentBase,因为两个函数的原型为:
PDEVICE_OBJECT IoGetDeviceAttachmentBaseRef(IN PDEVICE_OBJECT DeviceObject)
PDEVICE_OBJECT IopGetDeviceAttachmentBase(IN PDEVICE_OBJECT DeviceObject);

“取第一个参数时为什么用ebp+8”,要看函数调用在汇编中怎么实现的,见下图:

Debug版本一般使用ebp作栈寻址,而经过优化的Release 版本直接使用esp,省去了函数开头的“mov edi,edi; push ebp; mov ebp,esp;”,以及腾出ebp寄存器作为其它用途.而用ebp寻址的目的是为了方便调试分析,可通过[ebp+xx]方式直接看出寻址的是参数还是局部变量,而通过esp寻址只能往上推断,因为每次压栈(push)、弹栈(pop)都影响esp的位置。

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文