任何情况下,在寄存器的使用上,BASM遵循如下的规则:
- ASM语句执行过程中,必须保存EDI、ESI、ESP、EBP、EBX的值。
- ASM语句可以任意使用EAX、ECX、EDX。
- 一个ASM代码块开始时,EBP指向当前堆栈,ESP指向栈顶。
- SS存放堆栈段的段地址;DS存放数据段的段地址;CS存放代码段的段地址。
- 通常情况下,段地址寄存器满足如下条件:SS=ES=DS。
- 如果需要,函数总是以EAX(32位)、AX(16位)或AL(8位)作为返回值的寄存器。
Delphi的例程入口参数有以下几种:
procedure TestProc(I:Integer);//值参数 procedure TestProc(var I:Integer);//变量参数 procedure TestProc(const I:Integer);//常数参数 procedure TestProc (out I:Integer);//输出参数
按照Delphi的语法规定,值参数和常数参数使用相同的传值规则,但值参数只是传入值的备份;变量参数、输出参数总是传入值的地址。至于像“无类型参数”、“开放数组参数”等,都是在上面的基础上声明的,因此也符合其基本规则。
可以直接修改变量参数和输出参数传入的内存地址上的值,这种修改能被调用者识别和接收。
对于值参数,必要的情况下,编译器会生成一段代码,用于创建值参数的一个备份并用它的地址替换入口参数的地址。除此之外,值参数与常数参数使用相同规则:如果传入的数据长度小于或等于4Bytes(这存在一些例外,如Int64),则直接传值,否则传值的(对于值参数来说,是值的备份的)内存地址。
在不违背上述寄存器使用规则和例程参数传递规则的前提下,Delphi支持5种调用约定(如表3-1所列)。