__cdecl 调用约定不适用于 msvc x64

2024-02-01

只是一个测试__cdecl调用约定。

这是一个 cmake 项目,只有 1 个源文件:

#include <stdio.h>

#define CALL_CONVENTION __cdecl

void CALL_CONVENTION f(int a, int b)
{
    printf("%d, %d", a, b);
}

int main()
{
    f(1, 2);

    return 0;
}

我在用着set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /FA")输出汇编代码。

当我用cmake -G "Visual Studio 15",它正在构建一个 32 位应用程序,一切都在预料之中:

...
; Line 12
    push    ebp
    mov ebp, esp
; Line 13
    push    2        ; <------- argument 2
    push    1        ; <------- argument 1
    call    _f       ; <------- call function
    add esp, 8
; Line 15
    xor eax, eax
; Line 16
    cmp ebp, esp
    call    __RTC_CheckEsp
    pop ebp
    ret 0
_main   ENDP
...

你可以看到参数被传递了push 2 and push 1说明,它是__cdecl调用约定。

但如果我使用cmake -G "Visual Studio 15 Win64"要构建 64 位应用程序,__cdecl注释似乎不起作用(参数未通过堆栈传递):

...
; Line 12
$LN3:
    push    rdi
    sub rsp, 32                 ; 00000020H
    mov rdi, rsp
    mov ecx, 8
    mov eax, -858993460             ; ccccccccH
    rep stosd
; Line 13
    mov edx, 2        ; <------ argument 2
    mov ecx, 1        ; <------ argument 1
    call    f         ; <------ call function
; Line 15
    xor eax, eax
; Line 16
    add rsp, 32                 ; 00000020H
    pop rdi
    ret 0
main    ENDP
...

参数通过寄存器传递edx and ecx,不通过堆栈传递。

那么为什么即使我指定,参数在 x64 中也不会通过堆栈传递__cdecl如果我想在 x64 环境中做同样的事情我应该做什么。


x64 有它自己的调用约定。

微软文档__cdecl https://learn.microsoft.com/en-us/cpp/cpp/cdecl?view=vs-2019

在 ARM 和 x64 处理器上,__cdecl 被接受,但通常被编译器忽略。按照 ARM 和 x64 上的约定,如果可能,参数将在寄存器中传递,后续参数将在堆栈上传递。在 x64 代码中,使用 __cdecl 覆盖 /Gv 编译器选项并使用默认的 x64 调用约定。

Microsoft docs x64 calling convention https://learn.microsoft.com/en-us/cpp/build/x64-calling-convention?view=vs-2019

默认情况下,x64 应用程序二进制接口 (ABI) 使用四寄存器快速调用约定。在调用堆栈上分配空间作为被调用者保存这些寄存器的影子存储。函数调用的参数与用于这些参数的寄存器之间存在严格的一一对应关系。任何不能容纳 8 个字节或不是 1、2、4 或 8 个字节的参数都必须通过引用传递。

...

整数参数在寄存器 RCX、RDX、R8 和 R9 中传递

您可以使用 ECX 和 EDX 来查看它int a and int b(因为它们是 32 位,而完整的 RAX 和 RDX 是 64 位)。

__stdcall https://learn.microsoft.com/en-us/cpp/cpp/stdcall?view=vs-2019, __fastcall https://learn.microsoft.com/en-us/cpp/cpp/fastcall?view=vs-2019 and __thiscall https://learn.microsoft.com/en-us/cpp/cpp/thiscall?view=vs-2019也被忽略。__vectorcall https://learn.microsoft.com/en-us/cpp/cpp/vectorcall?view=vs-2019可用(/Gv 开关使其成为默认值),并且是另一种寄存器调用约定,但与 x64 默认值相比,它可以在更多情况下使用寄存器,并且有一些其他规则差异。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

__cdecl 调用约定不适用于 msvc x64 的相关文章

  • 如何在 DataColumn.Expression 中使用 IF/ELSE 或 CASE?

    我有一个包含 1 列的表 状态 我想添加另一列名为 Action 的列 其值如下 如果 Status Yes 则 Action Go 否则 Action Stop 我使用以下代码添加到 操作 列中 但它不起作用 myDataTable Co
  • 如何保证对象只有一个线程

    我有以下代码 class Service public void start creates thread which creates window and goes to message loop void stop sends WM C
  • FileStream 构造函数和默认缓冲区大小

    我们有一个使用 NET 4 用 C 编写的日志记录类 我想添加一个构造函数参数 该参数可以选择设置文件选项 WriteThrough http msdn microsoft com en us library system io fileo
  • VS 程序在调试模式下崩溃,但在发布模式下不崩溃?

    我正在 VS 2012 中运行以下程序来尝试 Thrust 函数查找 include cuda runtime h include device launch parameters h include
  • 根据 N 个值中最小的一个返回不同的结果

    不确定如何使标题更具描述性 所以我只是从一个例子开始 我使用下面的代码位 它从枚举中选择一个方向 具体取决于四个轴中哪一个与给定方向相比形成最小角度 static Direction VectorToDirection Vector2 di
  • 指向特征矩阵的指针数组

    我在代码中使用 Eigen 的 MatrixXd 矩阵 在某个时刻我需要一个 3D 矩阵 由于 Eigen 没有三维矩阵类型 因为它仅针对线性代数进行了优化 因此我创建了一个 MatrixXd 类型的指针数组 Eigen MatrixXd
  • vs2008 c#:Facebook.rest.api如何使用它来获取好友列表?

    如何在此基础上取得进一步的进步 获取好友列表的下一步是什么 string APIKey ConfigurationManager AppSettings API Key string APISecret ConfigurationManag
  • 如何在 QTabWidget Qt 中展开选项卡

    我有一个QTabWidget像这个 但我想展开选项卡以 填充 整个小部件宽度 如下所示 我怎样才能做到这一点 我在用Qt 5 3 2 and Qt 创建者 3 2 1 Update 我尝试使用setExpanding功能 ui gt myT
  • C++ php 和静态库

    我创建了一个library a 其中包含 cpp 和 h 文件 其中包含很多类 嵌套类和方法 我想在 php 示例中包含这个静态库并尝试使用它 我想提一下 我是 php 新手 我已经在 test cpp 文件中测试了我的 libray a
  • 将二进制数据从 C# 上传到 PHP

    我想将文件从 Windows C 应用程序上传到运行 PHP 的 Web 服务器 我知道 WebClient UploadFile 方法 但我希望能够分块上传文件 以便我可以监控进度并能够暂停 恢复 因此 我正在读取文件的一部分并使用 We
  • 如何在子 shell 中运行 cmd.exe 批处理文件

    我有一个批处理文件 通常像这样调用 longjob cmd gt result txt 2 gt 1 这工作正常 但脚本在执行过程中更改了目录 将我的 shell 留在该目录中 这很麻烦 有没有办法在子 shell 中运行命令 同时仍然允许
  • AES 输出是否小于输入?

    我想加密一个字符串并将其嵌入到 URL 中 因此我想确保加密的输出不大于输入 AES 是可行的方法吗 不可能创建任何始终会创建比输入更小的输出的算法 但可以将任何输出反转回输入 如果您允许 不大于输入 那么基本上您只是在谈论同构算法alwa
  • 如何在标准 WPF ListView 中启用 UI 虚拟化

    我正在使用 NET 4 5 VS2012 并且我有一个 ListView 看起来像这样
  • uri 警告中缺少端口:使用 Python OpenCV cv2.VideoCapture() 打开文件时出错

    当我尝试流式传输 ipcam 时 出现了如下所示的错误 tcp 000000000048c640 uri 中缺少端口 警告 打开文件时出错 build opencv modules videoio src cap ffmpeg impl h
  • 如何分析组合的 python 和 c 代码

    我有一个由多个 python 脚本组成的应用程序 其中一些脚本正在调用 C 代码 该应用程序现在的运行速度比以前慢得多 因此我想对其进行分析以查看问题所在 是否有工具 软件包或只是一种分析此类应用程序的方法 有一个工具可以将 python
  • C# 中的 strstr() 等效项

    我有两个byte 我想找到第二个的第一次出现byte 在第一个byte 或其中的一个范围 我不想使用字符串来提高效率 翻译第一个byte to a string会效率低下 基本上我相信就是这样strstr 在 C 中做 最好的方法是什么 这
  • .NET Core 中的跨平台文件名处理

    如何处理文件名System IO以跨平台方式运行类以使其在 Windows 和 Linux 上运行 例如 我编写的代码在 Windows 上完美运行 但它不会在 Ubuntu Linux 上创建文件 var tempFilename Dat
  • 跨多个域的 ASP.NET 会话

    是否有合适的 NET 解决方案来在多个域上提供持久服务器会话 即 如果该网站的用户在 www site1 com 下登录 他们也将在 www site2 com 下登录 安全是我们正在开发的程序的一个问题 Thanks 它是否需要在会话中
  • 每个数据库多个/单个 *.edmx 文件

    我有一个通过 ADO net 数据服务与数据库交互的项目 数据库很大 近 150 个具有依赖关系的表 该项目几年前开始 当时使用的是数据集 现在我们正在转向实体模型关系 由于我们添加了更多需要使用的表 该模型正在不断增长 这是管理这一切的正
  • xsi:type 属性搞乱了 C# XML 反序列化

    我使用 XSD exe 根据 XML 架构 xsd 文件 自动生成 C 对象 我正在反序列化 OpenCover 输出 但其中一个部分类未正确生成 这是导致异常的行

随机推荐

  • 视口单位 vw/vh/vmin/vmax 不支持缩放吗?

    As per 如何正确使用 css values viewport relative lengths https stackoverflow com questions 30175730 how to properly use css va
  • 将 Redis Streams 输出转换为 Pandas Dataframe

    会是什么fastest方法来转换一个Redis流 https redis io topics streams intro输出 aioredis 客户端 hiredis 解析器 到 Pandas Dataframe 其中 Redis 流 ID
  • 如何在 OS X 上重新启动 nginx

    我在用着nginx在 OS X 10 8 上 全新安装nginx但找不到重新启动 nginx 的方法 除了kill nginx pid say kill 64116 想知道是否有更好的重启方法nginx 在Google和SO上找到了一些方法
  • iPhone 使用证书加密

    我必须加密一个字符串 并在 xCode 项目的 Resources 文件夹中有一个 CER x 509 这两天我一直在想怎么做 但没有成功 所以是时候问一下了 Apple 的文档非常难以阅读 而且我认为这个框架可能是最难理解的框架 两个示例
  • React-ui-tree 对触摸设备的拖放支持

    我正在尝试为支持触摸的设备添加 DnD 支持反应 ui 树 https github com pqx react ui tree它的行为似乎很奇怪 虽然拖动似乎开始于触摸移动事件并突然停止 但如果你从同一个位置拾取并移动 那么事情似乎就会起
  • Java正则表达式以逗号分隔但忽略注释内的逗号

    我需要正则表达式用逗号 分割字符串 但忽略注释部分中的逗号 更改你的正则表达式后我尝试了很多 但没有成功 例如 Command RTRV EQPT Completion Code DENY Error Code II AC Problem
  • SQL Server:使用元组 IN 子句进行多重连接

    我正在尝试连接 4 个具有复杂关系的表 由于要使用它的位置 它需要包含在单个查询中 但我遇到了麻烦 因为主查询和 IN 子句查询都将 2 个表连接在一起 并且查找是在两列上进行的 目标是输入一个SalesNum and SalesType并
  • 使用 pygame.transform.rotate 时内存不足

    我写了一个脚本 允许用户控制老鹰的精灵飞来飞去以学习pygame 看起来很好 直到我实现了一个旋转函数 使精灵根据其飞行方向旋转 移动一小会儿后 精灵变得非常模糊 很快就会弹出一个错误 内存不足 在这一行 eagle img pygame
  • NullPointerException 但编译?

    我正在编写一个简单的命令行游戏 我已经有很多功能了 这里只发布必要的功能 问题 程序可以编译 但是当levelup 被呼叫并选择了一个号码 我得到这个 You have 5 skill points to spend What would
  • 实体子类的专用缓存区域?

    我们拥有一个包含 100 多个实体类的广泛实体模型 所有实体类都是单个实体超类的子类 共享缓存模式已设置为ALL Entity Inheritance strategy InheritanceType JOINED Table name e
  • 这是什么意思: qq = qq || {}? [复制]

    这个问题在这里已经有答案了 我已经下载了一个 JavaScript 脚本 第一行是 qq qq 这是什么意思 它检查qq对于预先存在的真实值 http 11heavens com falsy and truthy in javascript
  • 安装私有 Go 模块:未知修订错误

    我有一个私人 Go 存储库 位于https github com myorg myrepo被另一个 Go 存储库使用并定义在go mod 当我尝试跑步时 go mod tidy下载所有依赖项 它返回以下错误 go github com my
  • 处理400后运行时错误

    设想 用户名和密码使用 WebApi 2 令牌身份验证进行身份验证 如果凭据正确 则返回令牌 但是 如果凭据不正确 则会返回 400 bad request 在我的 Ionic 2 项目中 如果收到响应 我会导航到下一页 如果收到错误 我会
  • Java中使用Selenium快速获取每个WebElement的类属性

    我正在寻找每个的类属性WebElement用硒快速在页面上 目前 我正在执行以下操作 allElements new ArrayList
  • 当 setLabelsClipped 为 true 时,顶点标签在顶点外部、滚动条上和其他组件上绘制

    我使用 JGraph 一段时间了 当您将标签裁剪设置为 true 时 似乎存在绘画问题 下面的简化示例显示了您可能会遇到的实际应用程序中的问题 import java awt BorderLayout import java awt Dim
  • 在 MATLAB 中处理大型 CSV 文件

    我必须处理一个最大 2GB 的大 CSV 文件 更具体地说 我必须将所有这些数据上传到 mySQL 数据库 但在我必须对此进行一些计算之前 所以我需要在 MATLAB 中完成所有这些操作 我的主管也想在 MATLAB 中完成 因为他熟悉MA
  • 将嵌套 XML 数据与数据库表结构进行匹配的最快方法

    我有一个创建的应用程序datarequests这可能相当复杂 这些需要作为表存储在数据库中 一个轮廓datarequest 作为 XML 将是
  • 无法解析 MatDialogRef 角度 4 的所有参数

    我正在研究 Angular 4 我正在尝试设置材质包 在这里我尝试尝试对话框 但它不起作用 可能是因为我不确定材质包 这是我的 dialog components ts import Component OnInit from angula
  • NET::ERR_CERT_COMMON_NAME_INVALID - 错误消息

    前段时间我用 Flask 建立了一个网站 现在突然间 当我尝试导航到那里时 我得到以下信息 NET ERR CERT COMMON NAME INVALID 你的连接不是私人的 攻击者可能试图从 www mysite org 窃取您的信息
  • __cdecl 调用约定不适用于 msvc x64

    只是一个测试 cdecl调用约定 这是一个 cmake 项目 只有 1 个源文件 include