能力值:
( LV2,RANK:10 )
|
-
-
2 楼
reg
|
能力值:
( LV3,RANK:30 )
|
-
-
3 楼
64位寄存器多,寄存器回溯试试
|
能力值:
( LV5,RANK:68 )
|
-
-
4 楼
RtlWalkFrameChain
|
能力值:
( LV9,RANK:280 )
|
-
-
5 楼
RtlWalkFrameChain+1 原理自行阅读wrk源码
|
能力值:
( LV11,RANK:190 )
|
-
-
6 楼
如果是编译器产生的代码,实际上在正式进入函数之前,是会有把寄存器保存到栈中的操作的(你可以F11跟一下汇编代码就明白了),栈帧从形式上来讲和32位没有区别。(我说的是VS,其他的编译器没有研究)
|
能力值:
( LV3,RANK:35 )
|
-
-
7 楼
[rsp]啊 ,这不是一样的么。 64位 vs 编译的 fastcall只是把前4个参数用寄存器传了。 rcx rdx r8 r9
|
能力值:
( LV2,RANK:10 )
|
-
-
8 楼
fastcall其实就是thiscall+stdcall的变种版.....差别就是前4个参数分别会使用rcx,rdx,r8,r9,xmm0,xmm1,xmm2,xmm3中传递,当然如果是this调用的话,rcx就是保存对象自身的指针啦. 网上流传的文档描述大部分都是错误的,因为这个是微软专用的调用约定,所以看说明还是得看微软原版的说明: https://msdn.microsoft.com/zh-cn/library/ms235286.aspx 网上的文档说明,往往都忽略了浮点数参数的传递和参数位置对齐的问题. 比如参数1和2是整数,参数3和4是浮点数,参数5是整数,那么他们对应的位置是rcx,rdx,xmm2,xmm3,[rsp+(5*0x8)](进入函数体后,rbp会被压入栈顶),坑就坑在这个栈上面,编译器优化的话,为了保存快速调用,被压入寄存器的参数,依然会霸占栈内存的,而某些情况下,也可能出现不霸占栈内存的情况,这个纯属看编译器优化了. 类似的调用约定,和clrcall差不多.clrcall更坑,分为32位clrcall和64位clrcall,而64位clrcall又很像fastcall.... 之前我做JIT的时候,就被这些东西搞得晕坨坨的.
最后于 2018-11-26 22:45
被flarejune编辑
,原因:
|
能力值:
( LV2,RANK:10 )
|
-
-
9 楼
面试遇到了这个问题,看了下wrk中的RtlWalkFrameChain 64位版本。基本原理就是,x64函数开头会有分配栈空间的指令,结尾有回收栈空间的指令,RtlWalkFrameChain 内部调用 RtlVirtualUnwind 去搜索栈空间相关的指令,可以得到当前函数的栈大小,然后通过 rsp+当前函数栈大小回推返回地址和父函数的rsp,最终完成栈回溯。具体细节参考 RtlWalkFrameChain 。
最后于 2020-9-18 11:01
被Private丶编辑
,原因:
|
|
|