参数传递方法
李维的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方法,即从左到右)的更多相关文章

  1. Python的程序结构[1] -> 方法/Method[0] -> 类实例方法、私有方法和抽象方法

    类实例方法.私有方法和抽象方法 Python中最常用的就是类实例方法,类似于属性中的类实例属性,同时,也存在与私有属性类似方法,即私有方法,下面介绍这两种常见的方法,以及一种特殊意义的类实例方法 -- ...

  2. thinkphp3.0增加setInc、setDec方法

    thinkphp3.0增加setInc.setDec方法 thinkphp3.0增加setInc.setDec方法,今天查看thinkphp2.0的方法setInc.setDec时是这样写的: 而对于 ...

  3. C#2.0新增功能03 匿名方法

    连载目录    [已更新最新开发文章,点击查看详细] 在 2.0 之前的 C# 版本中,声明委托的唯一方式是使用命名方法. C# 2.0 引入匿名方法,在 C# 3.0 及更高版本中,Lambda 表 ...

  4. hadoop入门(3)——hadoop2.0理论基础:安装部署方法

    一.hadoop2.0安装部署流程         1.自动安装部署:Ambari.Minos(小米).Cloudera Manager(收费)         2.使用RPM包安装部署:Apache ...

  5. AntiXSS v4.0中Sanitizer.GetSafeHtmlFragment等方法将部分汉字编码为乱码的解决方案

    AntiXSS v4.0中Sanitizer.GetSafeHtmlFragment等方法将部分汉字编码为乱码的解决方案 以下代码为asp.net环境下,c#语言编写的解决方案.数据用Dictiona ...

  6. vc++6.0各种报错合集(附:VC++6.0调出打印窗口的方法)

    背景: 由于VC++6.0对于现在的我来说,只是一个工具,暂时没有太多的时间分配到这块去深究它,由于不明其原理,因此也只是在此把错误积累下来,以备下次相同错误出现时能快速排除,节省时间. 正文 一.出 ...

  7. C#3.0新特性之扩展方法介绍

    C#3.0扩展方法是给现有类型添加一个方法.现在类型即可是基本数据类型(如int,String等),也可以是自己定义的类.以下是引用片段: //Demo--1 //扩展基本类型 namespace T ...

  8. 【原创】VB6.0应用程序安装包的生成(Setup Factory 9.0制作安装包的方法)

    VB6.0应用程序安装包的生成,利用其自带的打包工具生成的安装程序很简陋,一点不美观:如果想让自己的应用程序安装的时候显得高大上一点,本教程提供使用Setup Factory 9.0制作安装包的方法. ...

  9. Object Pascal 方法与技巧

    4 方法与技巧 4.1 设置代码模板 代码模板是Delphi 的代码感知特性的一种,通过它可以快速.高效和正确地输入代码.代码模板将一些常用的语句块保存在模板中,然后程序员只要在代码编辑器中按下“Ct ...

随机推荐

  1. ModelConvertHelper(将DataTable转换成List<model>)

      public class ModelConvertHelper<T> where T : new() {      public static IList<T> Conve ...

  2. 用Photoshop做圆角图片

    如果图片被锁定,请“双击”图层中“背景”解锁,如果没有图层菜单,在最上面导航栏中:窗口—图层. 选用“圆角矩形工具“ 设置圆角弧度大小,设置“半径” 19 同时按Ctrl+回车(Enter)选区,再C ...

  3. ean128与code128 条形码 算法分析

    [code128条形码组成] 除终止符(STOP)由13个模块组成外,其他字符均由11个模块组成 就是说,如果用‘1’表示黑线(实模块),用‘0’表示白线(空模块),那么每表示一个字符就需要11条线, ...

  4. 常见tcp端口

    TCP端口 7 = 回显 9 = 丢弃 11 = 在线用户 13 = 时间服务 15 = 网络状态 17 = 每日引用 18 = 消息发送 19 = 字符发生器 20 = ftp数据 21 = 文件传 ...

  5. N使用exus2打造企业maven仓库(三)

    假设项目中,我没有使用maven,我应该做出选择,或为项目.或者用它来推动这个项目从maven.有人会问,为什么maven?无需maven我们没有很好的操作. 这里,只说两件事情我最欣赏:第一点是管理 ...

  6. 类似QtiPlot的veusz,sigmaplot,pymol

    qtiplot在win下没那么好编译 依赖很多外部包的 scidavis 和 labplot是从他fork出来的 比较接近Origin 可以用这两个 FreeBSD 的 ports 里有直接 cd / ...

  7. Qt QDebug等重定向到文件中

    源地址:http://blog.163.com/soyo_gogogo/blog/static/171414077201392705639321/ Qt的qDebug() 等函数,可以打印出十分细致的 ...

  8. linux安装Eclipse c++环境

    yum install eclipse     yum install eclipse-cdt

  9. [置顶] 用mootools实现checkbox全选功能

    全选时,所有的单个checkbox都要选中,反过来也可以实现 //全选按钮 $('chkall').addEvent('click',function(){ $$('input[name=" ...

  10. uva 568(数学)

    题解:从1開始乘到n,由于结果仅仅要最后一位.所以每乘完一次,仅仅要保留后5位(少了值会不准确,刚開始仅仅保留了一位.结果到15就错了,保留多了int会溢出,比方3125就会出错) 和下一个数相乘,接 ...