x64调用约定

2019-07-24 14:40:02 浏览数 (1)

x64网上说rcx,rdx,r8,r9,堆栈,但实际上,堆栈必须预留够相应的参数大小。比如传入rcx,rdx两个参数,则调用入口(call指令处rsp)必须上面要留2个寄存器大小的地址。而超过的部分,也就是需要用堆栈来传递的部分,则从调用入口处向上偏移4个处传递。也就是说前4个参数虽然用寄存器,但是堆栈的位置必须预留出来,以便于函数体内调用。难怪现在gcc编译出来的代码不使用压栈方式,而是直接改堆栈数据了。

以上研究结果来自于delphi cpu调试。

后又经过使用vc 2015编写x64DLL导出测试,跟delphi调试结果相同,而且不做堆栈平衡。由调用者在调用前分配好堆栈,类似于:

代码语言:javascript复制
fmmain.pas.137: begin
00000000006FB090 55               push rbp
00000000006FB091 4883EC40         sub rsp,$40
00000000006FB095 488BEC           mov rbp,rsp
00000000006FB098 48894D50         mov [rbp $50],rcx
00000000006FB09C 48895558         mov [rbp $58],rdx
...
...
...
fmmain.pas.146: end;
00000000006FB0E8 488D6540         lea rsp,[rbp $40]
00000000006FB0EC 5D               pop rbp
00000000006FB0ED C3               ret

0 人点赞