参数以声明的顺序(和pascal相同)被传递,前3个有资格的参数分别使用EAX、EDX和ECX寄存器。实数、方法指针、Variant、Int64和结构类型不能作为寄存器参数(没有资格),其它类型都可以。若具有资格的参数多于3个,前3个被选用,其余的以声明的顺序传给栈。比如,下面的声明中
procedure Test(A: Integer; var B: Char; C: Double; const D: string; E: Pointer);
A作为32位整数传给EAX,B作为字符指针(var参数)传给EDX,D作为指针传给ECX;C和E作为双字和指针被压入栈,和它们声明的顺序一样。
寄存器保存约定
过程和函数必须保留EBX、ESI、EDI和EBP寄存器,但可以修改EAX、EDX和ECX。当在汇编语言中实现构造和销毁时,保证预留DL寄存器。过程和函数被调用时,是假定CPU的direction标志是清除的(对应于CLD指令),并且返回时,direction标志也必须是清除的。
Function results(函数结果)
以下约定适用于函数的返回值:
z 可能的话,有序类型通过寄存器返回值:字节通过AL返回,字通过AX返回,双字通过EAX返
回。
z 实数类型的返回值在浮点协处理器的栈顶寄存器(top-of-stack register,ST(0))。对于Currency类
型的返回值,ST(0)中的值被乘以10000。比如,Currency值1.234在ST(0)中的值为12340。 z 对字符串、动态数组、方法指针、Variant、或Int64类型的返回值,就像函数在其它参数的后面额
外声明了一个var参数。换句话说,是函数调用者传递一个额外的32位指针,它指向的变量用来返回结果。
z 指针、类、类引用和过程指针类型,结果通过EAX返回。
z 对静态数组、记录和集合类型,若结果占用1个字节,它通过AL返回;若结果占用2个字节,
它通过AX返回;若结果占用4个字节,它通过EAX返回。否则(结果超过4个字节),结果通过一个额外的var参数返回,它在所有声明的参数的后边。
Method calls(方法调用)
方法和其它普通过程(和函数)使用相同的调用约定,除了每个方法有一个隐含的参数Self,这是一个实例或类的引用。Self参数作为32位指针传递。
在register调用约定下,Self就像在所有其它参数的前面声明,所以,它总是通过EAX寄存器传递。 在pascal调用约定下,Self就像在所有其它参数的后面声明(有时还要包括返回函数值的额外的var参数),所以,它最后被压入栈,所在的地址比其它参数要低。
在cdecl、stdcall和safecall调用约定下,Self就像在所有其它参数的前面声明,但却在作为函数返回值的额外的var参数之后(如果有的话),所以,除了额外的var参数,它最后一个被压入栈。 Constructors and destructors(构造函数和析构函数)
Constructor和destructor与其它方法使用相同的调用约定,除了传递一个附加的布尔类型的标志,它指示Constructor和destructor的调用环境。
对Constructor来说,若布尔标志是False,则表明是通过一个(对象)实例进行调用或使用inherited关键字,此时,它就像一个普通方法;若标志值是True,则表明是通过一个类引用进行调用,此时,constructor创建一个类实例(given by Self,通过Self给出),并在EAX中给出新对象的引用。
本文来自电脑杂谈,转载请注明本文网址:
http://www.pc-fly.com/a/jisuanjixue/article-23665-121.html
垃圾
猪乸也会上树