汇编-__fastcall前两个参数的堆栈问题
查看微软内部函数的时候用的是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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
是把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的位置。