You can write
complete procedures and functions using inline assembler code, without
including a begin...end statement. For example,
function
LongMul(X, Y: Integer): Longint;
asm
MOV EAX,X
IMUL Y
end;
The compiler performs several optimizations on these routines:
· No code is generated to copy value parameters into local variables. This affects all string-type value parameters and other value parameters whose size isn’t 1, 2, or 4 bytes. Within the routine, such parameters must be treated as if they were var parameters.
· Unless a function returns a string, variant, or interface reference, the compiler doesn’t allocate a function result variable; a reference to the @Result symbol is an error. For strings, variants, and interfaces, the caller always allocates an @Result pointer.
· The compiler only generates stack frames for nested routines, for routines that have local parameters, or for routines that have parameters on the stack.
· The automatically generated entry and exit code for the routine
looks like this:
PUSH EBP ;Present
if Locals <> 0 or Params <> 0
MOV EBP,ESP ;Present
if Locals <> 0 or Params <> 0
SUB ESP,Locals ;Present
if Locals <> 0
...
MOV ESP,EBP ;Present
if Locals <> 0
POP EBP ;Present
if Locals <> 0 or Params <> 0
RET Params ;Always
present
If locals include variants, long strings, or interfaces, they are initialized to zero but not finalized.
· Locals is the size of the local
variables and Params is the size of the parameters. If both Locals
and Params are zero, there is no entry code, and the exit code consists
simply of a RET instruction.
Assembler functions return their results as follows.
· Ordinal values are returned in AL (8-bit values), AX (16-bit values), or EAX (32-bit values).
· Real values are returned in ST(0) on the coprocessor’s register
stack. (Currency values are scaled by 10000.)
· Pointers, including long strings, are returned in EAX.
· Short strings and variants are returned in the temporary location pointed to by @Result.
Inline assembler code: Overview
Procedures
and functions: Overview
可以使用内嵌汇编程序代码完整地编写过程和函数,而不包括begin...end语句。例如,
function
LongMul(X, Y: Integer): Longint;
asm
MOV EAX,X
IMUL Y
end;
编译器对这样的例程将做如下优化:
· 不产生任何代码用于复制值参数到局部变量。这影响到所有的串类型的值参数以及其它尺寸不是1、2或4字节的值参数。在例程中,这样的参数必须被视为var参数。
· 除非函数返回一个串、变体或接口引用,否则编译器不会分配函数结果变量;对@Result符号的引用是错误的。对于串、变体和接口,调用者总是分配一个@Result指针。
· 编译器仅对嵌套例程产生栈的帧,对拥有局部参数的例程产生栈的帧,或者对于拥有栈参数的例程产生栈的帧。
· 为例程自动产生入口点和退出代码看起来如下:
PUSH EBP ;当Locals <> 0 或 Params <> 0时存在
MOV EBP,ESP ;当Locals <> 0 或 Params <> 0时存在
SUB ESP,Locals ;当Locals <> 0时存在
...
MOV ESP,EBP ;当Locals <> 0时存在
POP EBP ;当Locals <> 0 或 Params <> 0时存在
RET Params ;总是存在
如果局部变量包括变体、长串或接口,那么它们被初始化为零但不被结束处理。
· Locals是局部变量的尺寸,Params是参数的尺寸。如果Locals和Params都是零,那么这里没有入口代码,并且退出代码简单地由RET指令组成。
汇编函数如下返回其结果:
· 序数值在AL(8位值)、AX(17位值)或EAX(32位值)中返回。
· 实数值在数字协处理器栈的ST(0)中返回。(Currency值被乘以10000倍。)
· 指针,包括长串,在EAX中返回。
· 短串和变体在@Result指向的临时位置中返回。