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

前端开发 前端开发 主题:1148 回复:2395

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

想挽留 发布于 2016-11-17 字数 813 浏览 1008 回复 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 ?

发布评论

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

支持 Markdown 语法,需要帮助?

评论(1

想挽留 2017-01-26 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的位置。