The built-in assembler divides expressions
into three classes: registers, memory references, and immediate
values.
An expression that consists solely
of a register name is a register expression. Examples of register
expressions are AX, CL, DI, and ES. Used as operands, register expressions
direct the assembler to generate instructions that operate on the CPU
registers.
Expressions that denote memory
locations are memory references. Object Pascal’s labels, variables, typed
constants, procedures, and functions belong to this category.
Expressions that aren’t registers
and aren’t associated with memory locations are immediate values. This group
includes Object Pascal’s untyped constants and type identifiers.
Immediate values and memory
references cause different code to be generated when used as operands. For
example,
const
Start = 10;
var
Count: Integer;
...
asm
MOV
EAX,Start {
MOV EAX,xxxx }
MOV
EBX,Count {
MOV EBX,[xxxx] }
MOV
ECX,[Start] {
MOV ECX,[xxxx] }
MOV
EDX,OFFSET Count {
MOV EDX,xxxx }
end;
Because Start is an
immediate value, the first MOV is assembled into a move immediate instruction.
The second MOV, however, is translated into a move memory instruction, as Count
is a memory reference. In the third MOV, the brackets convert Start into
a memory reference (in this case, the word at offset 10 in the data segment).
In the fourth MOV, the OFFSET operator converts Count into an immediate
value (the offset of Count in the data segment).
The brackets and OFFSET operator
complement each other. The following asm statement produces identical
machine code to the first two lines of the previous asm statement.
asm
MOV
EAX,OFFSET [Start]
MOV
EBX,[OFFSET Count]
end;
Memory references and immediate
values are further classified as either relocatable or absolute.
Relocation is the process by which the linker assigns absolute addresses to
symbols. A relocatable expression denotes a value that requires relocation at
link time, while an absolute expression denotes a value that requires no such
relocation. Typically, expressions that refer to labels, variables, procedures,
or functions are relocatable, since the final address of these symbols is
unknown at compile time. Expressions that operate solely on constants are
absolute.
The built-in assembler allows you to carry out any operation on an absolute value, but it restricts operations on relocatable values to addition and subtraction of constants.
内建汇编程序把表达式分为三类:寄存器(registers)、内存引用(memory references)和立即值(immediate values)。
由单独的寄存器名称组成的表达式是一个寄存器表达式。寄存器表达式的范例:AX、CL、DI、ES。寄存器表达式作为操作数使用时,它直接编译产生操作CPU寄存器的指令。
表示内存位置的表达式是内存引用。Object
Pascal的标号、变量、类型常量、过程、函数等都属于此类。
既不是寄存器也与内存位置无关的表达式是立即值。这一类表达式包括Object Pascal的无类型常量和类型标识符。
当作为操作数使用时,立即值和内存引用导致产生不同的代码。例如,
const
Start = 10;
var
Count: Integer;
...
asm
MOV
EAX,Start {
MOV EAX,xxxx }
MOV
EBX,Count {
MOV EBX,[xxxx] }
MOV
ECX,[Start] {
MOV ECX,[xxxx] }
MOV
EDX,OFFSET Count {
MOV EDX,xxxx }
end;
因为Start是一个立即值,所以第一个MOV被汇编为一个立即传送指令。而第二个MOV被转换为一个内存传送指令,是因为Count是一个内存引用。在第三个MOV中,方括号把Start转换为一个内存引用(这时单字在数据段中的偏移量是10)。在第四个MOV中,OFFSET运算符把Count转换为一个立即值(数据段中Count的偏移量)。
方括号和OFFSET运算符互相补充。下面的asm语句与前面的asm语句中前两行产生相同的机器码:
asm
MOV
EAX,OFFSET [Start]
MOV
EBX,[OFFSET Count]
end;
内存引用和立即值可以进一步分为可再定位的(relocatable)和绝对的(absolute)。再定位处理是指连接器把绝对地址赋给符号。可再定位的表达式表示的值在连接时间请求再定位,而一个绝对表达式表示的值不需要再定位。典型的可再定位表达式有标号、变量、过程或函数符号等,因为这些符号在编译时其最终地址是未知的。单独作用于常量的表达式是绝对表达式。
内建汇编程序允许完成作用于绝对值(absolute value)上的任何操作,而对可再定位的值仅限于对常量的加法和减法操作。