当前位置:网站首页>2020-09-04:函数调用约定了解么?
2020-09-04:函数调用约定了解么?
2020-11-06 21:50:00 【福大大架构师每日一题】
福哥答案2020-09-04:
初级回答:
stdcall和cdecl两者的参数传递顺序都是从右向左。
不同点是stdcall在被调用函数 (Callee) 返回前,由被调用函数 (Callee) 调整堆栈。cdecl在被调用函数 (Callee) 返回后,由调用方 (Caller) 调整堆栈,每一个调用它的函数都包含清空堆栈的代码,所以产生的可执行文件大小会比调用_stdcall函数的大。
中级回答:
1.__stdcall
在被调用函数 (Callee) 返回前,由被调用函数 (Callee) 调整堆栈
参数从右向左压入堆栈。
函数名自动加前导的下划线,后面紧跟一个@符号 ,其后紧跟着参数的尺寸。
2.__cdecl
在被调用函数 (Callee) 返回后,由调用方 (Caller) 调整堆栈。
函数实参在线程栈上按照从右至左的顺序依次压栈。
函数结果保存在寄存器EAX/AX/AL中
浮点型结果存放在寄存器ST0中
编译后的函数名前缀以一个下划线字符
调用者负责从线程栈中弹出实参(即清栈)
8比特或者16比特长的整形实参提升为32比特长。
受到函数调用影响的寄存器(volatile registers):EAX, ECX, EDX, ST0 - ST7, ES, GS
不受函数调用影响的寄存器: EBX, EBP, ESP, EDI, ESI, CS, DS
RET指令从函数被调用者返回到调用者(实质上是读取寄存器EBP所指的线程栈之处保存的函数返回地址并加载到IP寄存器)
3.__fastcall
__fastcall调用的主要特点就是快,因为它是通过寄存器来传送参数的。
实际上__fastcall用ECX和EDX传送前两个DWORD或更小的参数,剩下的参数仍自右向左压栈传送,被调用的函数在返回前清理传送参数的内存栈。
__fastcall调用约定在输出函数名前加上一个“@”符号,后面也是一个“@”符号和其参数的字节数,格式为@function @number ,如double multi(double a, double b)的修饰名是@multi@16。
__fastcall和__stdcall很象,唯一差别就是头两个参数通过寄存器传送。注意通过寄存器传送的两个参数是从左向右的,即第1个参数进ECX,第2个进EDX,其他参数是从右向左的入栈,返回仍然通过EAX。
fastcall调用约定和stdcall类似,它意味着:
- 函数的第一个和第二个DWORD参数(或者尺寸更小的)通过ecx和edx传递,其他参数通过从右向左的顺序压栈;
- 被调用函数清理堆栈;
- 函数名修改规则同stdcall。
Fast Calling Convention,快速调用约定。通过使用寄存器解决效率问题。特点:
函数参数部分通过寄存器传递,函数中最左的两个DWORD(寄存器大小是双字)或者更小的参数,通过寄存器传递。剩下的从右到左堆栈传递。 函数名改编:“@函数名@函数参数字节大小十进制”。 返回方式同__stdcall。
4.__thiscall
thiscall是唯一一个不能明确指明的函数修饰,因为thiscall不是关键字。它是C++类成员函数缺省的调用约定。由于成员函数调用还有一个this指针,因此必须特殊处理,thiscall意味着:
- 参数从右向左入栈;
- 如果参数个数确定,this指针通过ecx传递给被调用者;如果参数个数不确定,this指针在所有参数压栈后被压入堆栈;
- 对参数个数不定的,调用者清理堆栈,否则函数自己清理堆栈。
主要用于解决this指针问题,使用寄存器传递this指针。返回方式同__stdcall.
5.__nakedcall
这是一个很少见的调用约定,一般程序设计者建议不要使用。编译器不会给这种函数增加初始化和清理代码,更特殊的是,不能用return返回返回值,只能用插入汇编返回结果。
6.__pascal
基于Pascal语言的调用约定,参数从左至右入栈(与cdecl相反)。被调用者负责在返回前清理堆栈。 此调用约定常见在如下16-bit 平台的编译器:OS/2 1.x,微软Windows 3.x,以及Borland Delphi版本1.x。
7.__vectorcall
目的是用来优化浮点向量运算,intel处理器种有很多浮点向量寄存器,传统的调用约定(stdcall cdecl fastcall thiscall) 都是通过通用寄存器(ecx edx /rcx rdx r8 r9)以及堆栈进行参数传递,所以调用的时候,浮点参数需要从栈获取。
要求尽可能在寄存器中传递参数。函数名改编为”@@函数名@参数字节数十进制”。这是微软自己添加的标准。
8.syscall
与cdecl类似,参数被从右到左推入堆栈中。EAX, ECX和EDX不会保留值。参数列表的大小被放置在AL寄存器中(?)。 syscall是32位OS/2 API的标准。
9.optlink
参数也是从右到左被推入堆栈。从最左边开始的三个字符变元会被放置在EAX, EDX和ECX中,最多四个浮点变元会被传入ST(0)到ST(3)中----虽然这四个参数的空间也会在参数列表的栈上保留。函数的返回值在EAX或ST(0)中。保留的寄存器有EBP, EBX, ESI和EDI。 optlink在IBM VisualAge编译器中被使用。
10.__clrcall
__clrcall是C++ .Net里面的。
版权声明
本文为[福大大架构师每日一题]所创,转载请带上原文链接,感谢
https://my.oschina.net/u/4553401/blog/4546546
边栏推荐
- To teach you to easily understand the basic usage of Vue codemirror: mainly to achieve code editing, verification prompt, code formatting
- What is alicloud's experience of sweeping goods for 100 yuan?
- An article takes you to understand CSS gradient knowledge
- python100例項
- 华为云微认证考试简介
- In depth to uncover the bottom layer of garbage collection, this time let you understand her thoroughly
- C# 调用SendMessage刷新任务栏图标(强制结束时图标未消失)
- Introduction to Google software testing
- Chainlink brings us election results into blockchain everipedia
- 【自学unity2d传奇游戏开发】如何让角色动起来
猜你喜欢
【字节跳动 秋招岗位开放啦】Ohayoo!放学别走,我想约你做游戏!!!
谷歌浏览器实现视频播放加速功能
Staying up late summarizes the key points of report automation, data visualization and mining, which is different from what you think
ES6 learning notes (2): teach you to play with class inheritance and class objects
游戏主题音乐对游戏的作用
GitHub: the foundation of the front end
How to play sortable JS vuedraggable to realize nested drag function of forms
StickEngine-架构11-消息队列(MessageQueue)
嘉宾专访|2020 PostgreSQL亚洲大会阿里云数据库专场:王涛
如何在终端启动Coda 2中隐藏的首选项?
随机推荐
What is the meaning of sector sealing of filecoin mining machine since the main network of filecoin was put online
如何对数据库账号权限进行精细化管理?
What is the purchasing supplier system? Solution of purchasing supplier management platform
C# 调用SendMessage刷新任务栏图标(强制结束时图标未消失)
Tron smart wallet PHP development kit [zero TRX collection]
An article will take you to understand CSS alignment
实用工具类函数(持续更新)
The method of realizing high SLO on large scale kubernetes cluster
Flink's datasource Trilogy 2: built in connector
What are the criteria for selecting a cluster server?
嘉宾专访|2020 PostgreSQL亚洲大会阿里云数据库专场:曾文旌
消息队列(MessageQueue)-分析
Using an example to understand the underlying processing mechanism of JS function
hdu3974 Assign the task線段樹 dfs序
Live broadcast preview | micro service architecture Learning Series live broadcast phase 3
An article will introduce you to CSS3 background knowledge
What is the tensor in tensorflow?
In depth to uncover the bottom layer of garbage collection, this time let you understand her thoroughly
一路踩坑,被迫聊聊 C# 代码调试技巧和远程调试
C語言I部落格作業03