__cdecl、__stdcall和__fastcall的调用方式完全相同
__cdecl, __stdcall and __fastcall are all called the exact same way?
我使用Visual C++2010和MASM作为我的x64汇编程序
这是我的C++代码:
// include directive
#include "stdafx.h"
// functions
extern "C" int Asm();
extern "C" int (convention) sum(int x, int y) { return x + y; }
// main function
int main()
{
// print asm
printf("Asm returned %d.n", Asm());
// get char, return
_getch();
return EXIT_SUCCESS;
}
我的组装代码:
; external functions
extern sum : proc
; code segment
.code
Asm proc
; create shadow space
sub rsp, 20o
; setup parameters
mov ecx, 10
mov edx, 15
; call
call sum
; clean-up shadow space
add rsp, 20o
; return
ret
Asm endp
end
我这样做的原因是为了学习不同的呼叫惯例。我会将sum的调用约定设为stdcall,并修改asm代码,使其以"stdcall"的方式调用sum。一旦我做到了,我就会打,比如说,快速呼叫,然后用asm的"快速呼叫"方式来称呼它。
但现在看看我的汇编代码。当我使用该代码时,无论sum是stdcall、fastcall还是cdecl,它都会编译、执行fine,并将25打印为我的sum。
我的问题是:如何以及为什么__cdecl、__stdcall和__fastcall都可以完全相同的方式调用?
问题是您正在为x64目标进行编译。来自MSDN
给定扩展的寄存器集,x64只使用__fastcall调用约定和基于RISC的异常处理模型。__fastcall模型使用寄存器作为前四个参数和堆栈帧以传递其他参数。
切换到针对x86目标的编译,您应该能够看到各种调用约定的作用。
据我所知,x64只使用__fastcall约定__cdecl和stdcall将被编译为__fastcall。
相关文章:
- 重载方法的方式会在使用临时调用时生成编译器错误
- 以线程安全的方式调用"QQuickPaintedItem::updateImage(const QImage&image)"(no QThread)
- 是否可以使用非常量指针调用非常量函数,以及当两个unique_ptrs指向同一个对象时程序的行为方式?
- 是否有一种非间接、非黑客的方式来保证 constexpr 函数仅在编译时可调用?
- 为什么我以前调用析构函数的方式会导致模因问题
- 以独立方式从 C 调用C++
- 调用多个选定函数并节省 RAM 的最佳方式
- 有没有办法在函数以编程方式返回的引用上多次调用函数? -元组动态访问
- 虚拟和非虚拟成员函数的调用方式有什么区别?
- 这些不同的方式在“ this”上调用操作员有什么区别
- 如何根据其ARITY(或编译时已知的其他信息)以不同的方式调用函数对象
- 是否可以在main中以类似于Boost.MinimalTestFacility的方式调用Boost.UnitTest测试
- 如果从动态分配的对象调用方法,是否可以以某种方式内联(编译器优化)
- 这将是在将函数分配给变量或一次又一次地调用函数之间使用函数结果的最佳方式
- 函数调用时局部变量在堆栈中的组织方式
- 通过以下方式调用函数有什么区别
- 此C++代码中以何种方式调用函数
- Opencv 函数只能以 C 代码方式调用,而不能以C++方式调用
- 如何以尽可能独立于平台的方式从 c++ 调用 .NET
- 如何在Windows中以编程方式从调用堆栈帧中读取函数参数