参数传递方法(Delphi1.0与win16API使用pascal方法,即从左到右)
参数传递方法
李维的InsideVCL《第一章》中提到Windows定义的回调函数
typedef LRESULT (CALLBACK*WNDPROC)(HWND,UNIT,WPARAM,LPARAM)
为了加快回调函数执行的效率,Microsoft使用了CALLBACK修饰关键词来定义WNDPROC,而CALLBACK则是定义成FAR PASCAL.
那么为什么FARPASCAL就会更快执行呢?以下为我的解释
(1)cdecl:
通常是C/C++所使用缺省的参数传递方式,它的传递方式是由右到左,而且当被调用的函数结束之后,将会由调用函数本身来清除堆栈上的参数数据。每一个调用它的函数都包含清空堆栈的代码,所以产生的可执行文件大小会比调用_stdcall函数的大。
(2)stdcall:
参数传递方式,也是由右到左,但是当被调用的函数结束之后,则是由被调用函数来清除堆栈上的参数数据,Win32API所有的输出函数都是采用此中参数传递方式
(3)pascal:
是Delphi1.0与win16API所使用的参数传递方式,它的传递方式是由左到右,而且由被调用函数来清除堆栈上的参数数据.
(4)fastcall:(delphi下关键字为register)
是Delphi默认所使用的参数传递方式, 主要特点就是快,因为它是通过寄存器来传送参数的(实际上,它用ECX和EDX传送前两个双字(DWORD)或更小的参数,剩下的参数仍旧自右向左压栈传送,被调用的函数在返回前清理传送参数的内存栈)
注:所以在引用C++动态库中的函数时,要注意参数的传递方式,一般使用stdcall.还要注意字符串类型,C++在传递字符串时,都是采用字符指针的类型(Char *),所以你在Delphi的程序中就必须使用PCHAR类型,而不是string类型.
(5)thiscall
仅仅应用于“C++”成员函数。this指针存放于CX/ECX寄存器中,参数从右到左压。thiscall不是关键词,因此不能被程序员指定。
(6)naked call。
当采用1-4的调用约定时,如果必要的话,进入函数时编译器会产生代码来保存ESI,EDI,EBX,EBP寄存器,退出函数时则产生代码恢复这些寄存器的内容。(这些代码称作 prologand epilog code,一般,ebp,esp的保存是必须的).但是naked call不产生这样的代码。naked call不是类型修饰符,故必须和_declspec共同使用。
汇编测试
其實。你只要寫一段下去測試。看它的 asm 就知道了。
1.触发代码
TForm1.Test1Click(1,2, 3);
begin
0044E298 6A03 push$03
0044E29A 6A02 push$02
0044E29C 6A01 push$01
0044E29E 50 pusheax
0044E29F E8D4FFFFFF call TForm1.Test1
end
0044E2A4 C3 ret
0044E2A5 8D4000 lea eax,[eax+$00]
TForm1.Test2Click(1,2, 3);
begin
0044E287 6A03 push $03
0044E289 B902000000 mov ecx,$00000002
0044E28E BA01000000 mov edx,$00000001
0044E293 8BC3 mov eax,ebx
0044E295 E8CEFFFFFF call TForm1.Test2
end
0044E2B9 C3 ret
0044E2BA 8BC0 mov eax,eax
2.函数源码
FunctionTForm1.Test1(a, b, c: Integer): Integer; stdcall;
Begin
0044E268 55 push ebp
0044E269 8BEC mov ebp,esp
Result := a + b + c;
0044E25B 8B450C mov eax,[ebp+$0c]
0044E25E 034510 add eax,[ebp+$10]
0044E261 034514 add eax,[ebp+$14]
end
0044E264 5D pop ebp
0044E265 C21000 ret $0010
FunctionTForm1.Test2(a, b, c: Integer): Integer; register;
Begin
0044E268 55 push ebp
0044E269 8BEC mov ebp,esp
Result := a + b + c;
0044E26B 8D0411 lea eax,[ecx+edx]
0044E26E 034508 add eax,[ebp+$08]
end
0044E271 5D pop ebp
0044E272 C20400 ret $0004
0044E275 8D4000 lea eax,[eax+$00]
這样看起來。是不是就有所差別了?
http://blog.csdn.net/shuaihj/article/details/7162190
参数传递方法(Delphi1.0与win16API使用pascal方法,即从左到右)的更多相关文章
- Python的程序结构[1] -> 方法/Method[0] -> 类实例方法、私有方法和抽象方法
类实例方法.私有方法和抽象方法 Python中最常用的就是类实例方法,类似于属性中的类实例属性,同时,也存在与私有属性类似方法,即私有方法,下面介绍这两种常见的方法,以及一种特殊意义的类实例方法 -- ...
- thinkphp3.0增加setInc、setDec方法
thinkphp3.0增加setInc.setDec方法 thinkphp3.0增加setInc.setDec方法,今天查看thinkphp2.0的方法setInc.setDec时是这样写的: 而对于 ...
- C#2.0新增功能03 匿名方法
连载目录 [已更新最新开发文章,点击查看详细] 在 2.0 之前的 C# 版本中,声明委托的唯一方式是使用命名方法. C# 2.0 引入匿名方法,在 C# 3.0 及更高版本中,Lambda 表 ...
- hadoop入门(3)——hadoop2.0理论基础:安装部署方法
一.hadoop2.0安装部署流程 1.自动安装部署:Ambari.Minos(小米).Cloudera Manager(收费) 2.使用RPM包安装部署:Apache ...
- AntiXSS v4.0中Sanitizer.GetSafeHtmlFragment等方法将部分汉字编码为乱码的解决方案
AntiXSS v4.0中Sanitizer.GetSafeHtmlFragment等方法将部分汉字编码为乱码的解决方案 以下代码为asp.net环境下,c#语言编写的解决方案.数据用Dictiona ...
- vc++6.0各种报错合集(附:VC++6.0调出打印窗口的方法)
背景: 由于VC++6.0对于现在的我来说,只是一个工具,暂时没有太多的时间分配到这块去深究它,由于不明其原理,因此也只是在此把错误积累下来,以备下次相同错误出现时能快速排除,节省时间. 正文 一.出 ...
- C#3.0新特性之扩展方法介绍
C#3.0扩展方法是给现有类型添加一个方法.现在类型即可是基本数据类型(如int,String等),也可以是自己定义的类.以下是引用片段: //Demo--1 //扩展基本类型 namespace T ...
- 【原创】VB6.0应用程序安装包的生成(Setup Factory 9.0制作安装包的方法)
VB6.0应用程序安装包的生成,利用其自带的打包工具生成的安装程序很简陋,一点不美观:如果想让自己的应用程序安装的时候显得高大上一点,本教程提供使用Setup Factory 9.0制作安装包的方法. ...
- Object Pascal 方法与技巧
4 方法与技巧 4.1 设置代码模板 代码模板是Delphi 的代码感知特性的一种,通过它可以快速.高效和正确地输入代码.代码模板将一些常用的语句块保存在模板中,然后程序员只要在代码编辑器中按下“Ct ...
随机推荐
- POJ 3986 Math teacher's homework
题目 给出\(n,m_1,m_2,...,m_n\),求\(x_1 xor x_2 xor ... xor x_n=k (0 \leq x_i \leq m_i)\)的解的数量.二进制位数小于\(32 ...
- java字符操作获取汉字的拼音以及其它经常使用工具
公司需求年年有,今年有点小特殊,哈哈. 忽然加了个需求,说要实现汉字转拼音查询. 在努力下写出来了,如今分享一下吧!.! /** * 汉字转拼音缩写 * * @param str * 要转换的汉字字符 ...
- Tuxedo入门学习
中间件介绍: 介于客户机和server之间的夹层,突破了传统的c/s架构,为构建大规模,高性能,分布式c/s应用程序提供了通信,事物,安全,容错等基础服务,屏蔽了底层应用细节,应用程序不必从底层开发, ...
- (1)ActivityThread分析
1. 入口. 曾经一直都说Activity的人口是onCreate方法.事实上android上一个应用的入口,应该是ActivityThread.和普通的java类一样,入口是一个main方法. pu ...
- 你真的知道为什么不推荐使用@import?
Difference between @import and link in CSS Use of @import <style type="text/css">@im ...
- 反应堆Reactor
mvn -h 可以看到很多命令及其用途:-am --also-make 同时构建所列模块的依赖模块:-amd -also-make-dependents 同时构建依赖于所列模块的模块:-pl --pr ...
- dump json 显示中文问题
[root@dr-mysql01 ~]# cat a2.pl my $url="http://192.168.32.101:3000/api/getcode?env=zj&phone ...
- U盘安装Ubuntu kylin版
初试U盘安装Ubuntu14.04 kylin版 等待Ubuntu14.04 kylin版出来后,一直想要尝试在物理机进行安装体验,恰巧碰到五一假期,因为咱是穷人,没钱出去玩,所以就有了时间实地进行 ...
- MSSQL - 用GUID值来完成数据表行标识
地址:http://www.cnblogs.com/huangfr/archive/2012/03/28/2420780.html [Guid] [uniqueidentifier] NOT NULL ...
- ASP.NET - 上传图片方法(单张)
/// <summary> /// 上传图片 /// </summary> /// <param name="fileupload">上传的控件 ...