zoukankan      html  css  js  c++  java
  • x64的调用约定

    在设计调用约定时,x64 体系结构利用机会清除了现有 Win32 调用约定(如 __stdcall、__cdecl、__fastcall、_thiscall 等)的混乱。在 Win64 中,只有一个本机调用约定和 __cdecl 之类的修饰符被编译器忽略。除此之外,减少调用约定行为还为可调试性带来了好处。

    需要了解的有关 x64 调用约定的主要内容是:它与 x86 fastcall 约定的相似之处。使用 x64 约定,会将前 4 个整数参数(从左至右)传入指定的 64 位寄存器:

    RCX: 1st integer argumentRDX: 2nd integer argumentR8: 3rd integer argumentR9: 4th integer argument
    前 4 个以外的整数参数将传递到堆栈。该指针被视为整数参数,因此始终位于 RCX 寄存器内。

    对于浮点参数,前 4 个参数将传入 XMM0 到 XMM3 的寄存器,后续的浮点参数将放置到线程堆栈上。

    更进一步探究调用约定,即使参数可以传入寄存器,编译器仍然可以通过消耗 RSP 寄存器在堆栈上为其预留空间。至少,每个函数必须在堆栈上预留 32 个字节(4 个 64 位值)。该空间允许将传入函数的寄存器轻松地复制到已知的堆栈位置。不要求被调用函数将输入寄存器参数溢出至堆栈,但需要时,堆栈空间预留确保它可以这样做。当然,如果要传递 4 个以上的整数参数,则必须预留相应的额外堆栈空间。

    例如:

    int Add(int a,int b,int c,int d,int e)
    {
        return a+b+c+d+e;
    }
      Add(2,3,4,5,6);
    000000013FBD2DF1  mov         dword ptr [rsp+20h],6  
    000000013FBD2DF9  mov         r9d,5  
    000000013FBD2DFF  mov         r8d,4   //前四个参数寄存器传参
    000000013FBD2E05  mov         edx,3  
    000000013FBD2E0A  mov         ecx,2  
    000000013FBD2E0F  call        Add (13FBD100Fh)
  • 相关阅读:
    pat 1123 Is It a Complete AVL Tree
    pat 1098 Insertion or Heap Sort
    pat 1147 Heaps
    Python中的Dict底层 | 字典类型删除数据为什么不直接删除?
    MySQL | 重置root密码
    MySQL | 安装后初次使用
    安装MySQL | 报缺失文件的错误
    IDEA | 不使用骨架创建Maven项目
    python | list.sort()和sorted(list)的区别
    python | 字符串不可修改
  • 原文地址:https://www.cnblogs.com/lanrenxinxin/p/4450168.html
Copyright © 2011-2022 走看看