汇编语言Microsoft x64调用规范简介

< 上一页LOCAL伪指令 递归及应用详解下一页 >

Microsoft 遵循固定模式实现 64 位编程中的参数传递和子程序调用,该模式被称为 Microsoft x64 调用规范(Microsoft x64 calling convention)。它既用于 C 和 C++ 编译器,也用于 Windows API库。

只有在要么调用 Windows 函数,要么调用 C 和 C++ 函数时,才需要使用这个调用规范。它的特点和要求如下所示:

1) 由于地址长为 64 位,因此 CALL 指令把 RSP(堆栈指针)寄存器的值减去8。

2) 第一批传递给子程序的四个参数依次存放于寄存器 RCX、RDX、R8 和 R9。因此,如果只传递一个参数,它就会被放入 RCX。如果还有第二个参数,它就会被放入 RDX,以此类推。其他参数按照从左到右的顺序入栈。

3) 长度不足 64 位的参数不进行零扩展,因此,其高位的值是不确定的。

4) 如果返回值的长度小于或等于 64 位,那么它必须放在 RAX 寄存器中。

5) 主调者要负责在堆栈中分配至少 32 字节的影子空间,以便被调用的子程序可以选择将寄存器保存在这个区域中。

6) 调用子程序时,堆栈指针(RSP)必须对齐 16 字节边界。CALL 指令将 8 字节的返回地址压入堆栈,因此,主调程序除了把堆栈指针减去 32 以便存放寄存器参数之外,还要减去8。

7) 被调用子程序执行结束后,主调程序需负责从运行时堆栈中移除所有的参数和影子空间。

8) 大于 64 位的返回值存放于运行时堆栈,由 RCX 指出其位置。

9) 寄存器 RAX、RCX、RDX、R8、R9、R10 和 R11 常常被子程序修改,因此,如果主调程序想要保存它们的值,就应在调用子程序之前将它们入栈,之后再从堆栈弹出。

10) 寄存器 RBX、RBP、RDI、RSI、R12、R13、R14 和 R15 的值必须由子程序保存。
< 上一页LOCAL伪指令 递归及应用详解下一页 >

编程帮,一个分享编程知识的公众号。跟着站长一起学习,每天都有进步。

通俗易懂,深入浅出,一篇文章只讲一个知识点。

文章不深奥,不需要钻研,在公交、在地铁、在厕所都可以阅读,随时随地涨姿势。

文章不涉及代码,不烧脑细胞,人人都可以学习。

当你决定关注「编程帮」,你已然超越了90%的程序员!

编程帮二维码
微信扫描二维码关注