calling conventions on x86 platform --- 转载

原创 2007年10月07日 19:45:00

Calling conventions on the x86 platform

2005/02/13, Andreas Jonsson

This is a document that I wrote as research for the AngelCode Scripting Library. Since the library uses assembly to make the interaction between the script engine and the host application I needed to have complete knowledge of how the calling conventions are implemented by different compilers. To my surprise there were a lot more differences than I had initially thought. Most of the differences are related to C++ features, so the differences can be understood as there were no standard when the compilers were first written. Today there is a standard, but I believe that it doesn't mention how calling conventions should be implemented. Which leads to binary incompatibility between compilers, even though the source code is compatible.

The differences doesn't stop AngelScript from supporting each of the compilers. Though new compilers may have to make a few changes in order to follow the conventions used. As support for more compilers are added to AngelScript I will add those compilers to the article.




=== cdecl ===

This calling convention is the default for C programs and also global functions in C++ programs. Generally the function arguments are passed on the stack in reverse order so that the callee can access them in the correct order. The caller is responsible for popping the arguments after the function returns, which makes it possible to use the ... to send runtime defined arguments. Return values are returned in the registers.

Visual C++ / Win32

  • Arguments are pushed on the stack in reverse order.
  • The caller pops arguments after return.
  • Primitive data types, except floating point values, are returned in EAX or EAX:EDX depending on the size.
  • float and double are returned in fp0, i.e. the first floating point register.
  • Simple data structures with 8 bytes or less in size are returned in EAX:EDX.
  • Class objects that require special treatment by the exception handler are returned in memory. Classes with a defined constructor, destructor, or overloaded assignment operator are examples of these.
  • Objects larger than 8 bytes are returned in memory.
  • When a return is made in memory the caller passes a pointer to the memory location as the first parameter (hidden). The callee populates the memory, and returns the pointer. The caller pops the hidden pointer together with the rest of the arguments.
MinGW g++ / Win32

  • Arguments are pushed on the stack in reverse order.
  • The caller pops arguments after return.
  • Primitive data types, except floating point values, are returned in EAX or EAX:EDX depending on the size.
  • float and double are returned in fp0, i.e. the first floating point register.
  • Objects with 8 bytes or less in size are returned in EAX:EDX.
  • Objects larger than 8 bytes are returned in memory.
  • Classes that have a destructor are returned in memory regardless of size.
  • When a return is made in memory the caller passes a pointer to the memory location as the first parameter (hidden). The callee populates the memory, and returns the pointer. The callee pops the hidden pointer from the stack when returning.
  • Classes that have a destructor are always passed by reference, even if the parameter is defined to be by value.
GCC g++ / Linux

  • Arguments are pushed on the stack in reverse order.
  • The caller pops arguments after return.
  • Primitive data types, except floating point values, are returned in EAX or EAX:EDX depending on the size.
  • float and double are returned in fp0, i.e. the first floating point register.
  • All structures and classes are returned in memory regardless of complexity or size.
  • When a return is made in memory the caller passes a pointer to the memory location as the first parameter (hidden). The callee populates the memory, and returns the pointer. The callee pops the hidden pointer from the stack when returning.
  • Classes that have a destructor are always passed by reference, even if the parameter is defined to be by value.



=== stdcall ===

stdcall is the calling conventions used by the Win32 API. It is basically the same as the cdecl convention with the difference in that the callee is responsible for popping the arguments from the stack. This makes the call slightly faster, but also prevents the use of the ... operator.

Visual C++ / Win32

  • Arguments are pushed on the stack in reverse order.
  • The callee pops arguments when returning.
  • Primitive data types, except floating point values, are returned in EAX or EAX:EDX depending on the size.
  • float and double are returned in fp0, i.e. the first floating point register.
  • Simple data structures with 8 bytes or less in size are returned in EAX:EDX.
  • Class objects that require special treatment by the exception handler are returned in memory. Classes with a defined constructor, destructor, or overloaded assignment operator are examples of these.
  • Objects larger than 8 bytes are returned in memory.
  • When a return is made in memory the caller passes a pointer to the memory location as the first parameter (hidden). The callee populates the memory, and returns the pointer. The callee pops the hidden pointer together with the rest of the arguments.
MinGW g++ / Win32

  • Arguments are pushed on the stack in reverse order.
  • The callee pops arguments when returning.
  • Primitive data types, except floating point values, are returned in EAX or EAX:EDX depending on the size.
  • float and double are returned in fp0, i.e. the first floating point register.
  • Objects with 8 bytes or less in size are returned in EAX:EDX.
  • Objects larger than 8 bytes are returned in memory.
  • Classes that have a destructor are returned in memory regardless of size.
  • When a return is made in memory the caller passes a pointer to the memory location as the first parameter (hidden). The callee populates the memory, and returns the pointer. The callee pops the hidden pointer from the stack together with the rest of the arguments.
  • Classes that have a destructor are always passed by reference, even if the parameter is defined to be by value.
GCC g++ / Linux

  • Arguments are pushed on the stack in reverse order.
  • The callee pops arguments when returning.
  • Primitive data types, except floating point values, are returned in EAX or EAX:EDX depending on the size.
  • float and double are returned in fp0, i.e. the first floating point register.
  • All structures and classes are returned in memory regardless of complexity and size.
  • When a return is made in memory the caller passes a pointer to the memory location as the first parameter (hidden). The callee populates the memory, and returns the pointer. The callee pops the hidden pointer from the stack together with the rest of the arguments.
  • Classes that have a destructor are always passed by reference, even if the parameter is defined to be by value.
=== thiscall ===

This calling convention was introduced with C++. The only sure thing about it is that arguments are pushed on the stack in reverse order and that the caller passes the object pointer to the function in some way or other.

Visual C++ / Win32

  • Arguments are pushed on the stack in reverse order.
  • The object pointer is passed in ECX.
  • The callee pops arguments when returning.
  • Primitive data types, except floating point values, are returned in EAX or EAX:EDX depending on the size.
  • float and double are returned in fp0, i.e. the first floating point register.
  • Simple data structures with 8 bytes or less in size are returned in EAX:EDX.
  • All classes and structures are returned in memory, regardless of size.
  • When a return is made in memory the caller passes a pointer to the memory location as the first parameter (hidden). The callee populates the memory, and returns the pointer. The callee pops the hidden pointer together with the rest of the arguments.
  • If the method takes variable number of arguments, i.e. is declared with the ... operator, then the calling convention instead becomes that of cdecl. The object pointer is pushed on the stack as the first argument instead of passed in ECX, and all arguments are popped from the stack by the caller when the function returns.
MinGW g++ / Win32

  • Arguments are pushed on the stack in reverse order.
  • The object pointer is pushed on the stack as the first parameter.
  • The caller pops arguments after return.
  • Primitive data types, except floating point values, are returned in EAX or EAX:EDX depending on the size.
  • float and double are returned in fp0, i.e. the first floating point register.
  • Objects with 8 bytes or less in size are returned in EAX:EDX.
  • Objects larger than 8 bytes are returned in memory.
  • Classes that have a destructor are returned in memory regardless of size.
  • When a return is made in memory the caller passes a pointer to the memory location as the first parameter (hidden). The callee populates the memory, and returns the pointer. The callee pops the hidden pointer from the stack when returning.
  • Classes that have a destructor are always passed by reference, even if the parameter is defined to be by value.
GCC g++ / Linux

  • Arguments are pushed on the stack in reverse order.
  • The object pointer is pushed on the stack as the first parameter.
  • The caller pops arguments after return.
  • Primitive data types, except floating point values, are returned in EAX or EAX:EDX depending on the size.
  • float and double are returned in fp0, i.e. the first floating point register.
  • All structures and classes are returned in memory regardless of complexity and size.
  • When a return is made in memory the caller passes a pointer to the memory location as the first parameter (hidden). The callee populates the memory, and returns the pointer. The callee pops the hidden pointer from the stack when returning.
  • Classes that have a destructor are always passed by reference, even if the parameter is defined to be by value.



=== fastcall ===

This is a special calling convention that is designed for speed. It is rarely used so I haven't studied it closely, but I understand that the first arguments are passed in registers while the rest are pushed on the stack as normal. Visual C++ / Win32

  • The first two arguments are passed in ECX and EDX. The rest are passed on the stack just like cdecl
=== Further reading ===

Not all of these articles are directly related to calling conventions, but they are still a worthy read for anyone interested in interacting with C++ programs on a truly low level.




=== Revision history ===

  • 2004/08/04 - Article created.
  • 2005/01/19 - Added information on GCC/g++ on Linux. Made a few corrections on the way MinGW/g++ handles classes with declared destructors.
  • 2005/02/13 - Added information about class methods with variable number of arguments for MSVC++.
 

Linux设备模型(下)之Platform

从Linux2.6内核起,引入一套新的驱动管理和注册机制:platform_device和 platform_driver 。Linux 中大部分的设备驱动,都可以使用这套机制,设备用 platfor...
  • newnewman80
  • newnewman80
  • 2013年08月26日 15:54
  • 1133

C# 编译器选项 /platform(指定输出平台)32位程序运行到x64平台的问题

如果说你编译的exe运行时报错: “尝试读取或写入受保护的内存。这通常指示其他内存已损坏” 这很有可能是你是以非托管的方式错误地引用了64位的API中去。 为什么会这样? 那你就要...
  • kongfl888
  • kongfl888
  • 2013年10月01日 15:15
  • 1647

csdn如何转载别人的文章

csdn如何转载别人的文章
  • stonesing
  • stonesing
  • 2016年08月25日 17:07
  • 2091

csdn如何转载别人的文章

转载地址:http://blog.csdn.net/jiangping_zhu/article/details/18044109 1、找到要转载的文章,用chrome浏览器打开,右键选择审查元...
  • dlhlSC
  • dlhlSC
  • 2016年08月19日 16:51
  • 5065

csdn如何转载别人的文章

##转载于:http://blog.csdn.net/jiangping_zhu/article/details/18044109 ##作者:包心菜加糯米饭 1、找到要转载的文章,用chrome浏览...
  • mzpmzk
  • mzpmzk
  • 2016年05月24日 10:56
  • 11870

csdn如何转载别人的文章

对于喜欢逛CSDN的人来说,看别人的博客确实能够对自己有不小的提高,有时候看到特别好的博客想转载下载,但是不能一个字一个字的敲了,这时候我们就想快速转载别人的博客,把别人的博客移到自己的空间里面,当然...
  • Bleachswh
  • Bleachswh
  • 2016年12月19日 11:08
  • 1512

x86-64栈帧布局分布

摘自:http://eli.thegreenplace.net/2011/09/06/stack-frame-layout-on-x86-64A few months ago I’ve written...
  • chinaclock
  • chinaclock
  • 2015年12月16日 21:06
  • 1254

如何快速转载CSDN中的博客

前言  对于喜欢逛CSDN的人来说,看别人的博客确实能够对自己有不小的提高,有时候看到特别好的博客想转载下载,但是不能一个字一个字的敲了,这时候我们就想快速转载别人的博客,把别人的博客移到自己的空间里...
  • bolu1234
  • bolu1234
  • 2016年07月09日 15:59
  • 12199

学习日志-onMeasure等问题

一、 注意:从Android2.2开始,为了更好的使用,fill_parent被改为match_parent。因为当我们把一个子部件设置为fill_parent之后,该部件不是占有同等级部件剩余的空...
  • dacainiao007
  • dacainiao007
  • 2013年08月14日 16:32
  • 1584

CSDN怎么转载别人的博客

以最新的google为例,来说说我们在阅读csdn遇到别人的好文章转载的办法; 首先,我们找到别人的博客,使用F12审查元素,如下: 找到article_content之后,鼠标右键,按照...
  • ILV_XJ
  • ILV_XJ
  • 2017年05月24日 16:07
  • 256
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:calling conventions on x86 platform --- 转载
举报原因:
原因补充:

(最多只允许输入30个字)