翻译一半的Delphi汇编帮助

来源:互联网 发布:淘宝能买彩票吗 编辑:程序博客网 时间:2024/05/01 20:17

 The built-in assembler allows you to write assembly code within Delphi programs. It has the following features:
内嵌的汇编器允许在delphi程序中书写汇编代码,他有如下特性:

Allows for inline assembly
允许内嵌汇编
    Supports all instructions found in the Intel Pentium III, Intel MMX extensions, Streaming SIMD
 Extensions (SSE), and the AMD Athlon (including 3D Now!)
支持所有指令,如英特尔奔三处理器,英特尔MMX扩展,Streaming SIMD扩展(SSE),以及AMD Athlon处理器(包括3D)
    Provides no macro support, but allows for pure assembly function procedures
不提供宏支持,但允许纯汇编函数过程
    Permits the use of Delphi identifiers, such as constants, types, and variables in assembly statements
允许使用delphi标识符,诸如在汇编段内的常量,类型和变量
As an alternative to the built-in assembler, you can link to object files that contain external procedures and functions. See External declarations for more information.
当替代内置汇编的时候,你可以链接到一个包含有外部过程和函数的目标文件。更多的信息查看外部声明。

Note
注意,如果你有外部汇编代码,你想把它们用在你的应用程序中,你要考虑在Delphi中重写他,或者最底限度的使用内嵌汇编来实现。
If you have external assembly code that you want to use in your applications, you should consider rewriting it in the Delphi language or minimally reimplement it using the inline assembler.


The built-in assembler is accessed through asm statements, which have the form
内嵌汇编通过asm标识符来存储,使用end段来结束。
asm statementList end

where statementList is a sequence of assembly statements separated by semicolons, end-of-line characters, or Delphi comments.
汇编段使用分号来分割汇编代码段,字符的末尾可以使用delphi注释。

Comments in an asm statement must be in Delphi style. A semicolon does not indicate that the rest of the line is a comment.
内嵌汇编的注释必须是delphi的风格,分号并不能表示当前行剩余部分就是注释。

The reserved word inline and the directive assembler are maintained for backward compatibility only. They have no effect on the compiler.
保留字内联汇编指示符是向后兼容的,他们对编译器没有影响。

Register use
寄存器的使用
In general, the rules of register use in an asm statement are the same as those of an external procedure or function. An asm statement must preserve the EDI, ESI, ESP, EBP, and EBX registers, but can freely modify the EAX, ECX, and EDX registers. On entry to an asm statement, EBP points to the current stack frame and ESP points to the top of the stack. Except for ESP and EBP, an asm statement can assume nothing about register contents on entry to the statement.

一般情况下,内嵌汇编段的寄存器使用规则同外部的过程或函数的是相同的。汇编中必须保留EDI,ESI,ESP,EBP和EBX寄存器,但EAX,ECX和EDX寄存器可以随意的修改。在汇编段的入口,EBP指向当前堆栈帧,ESP执行堆栈的顶部。除了ESP和EBP,汇编段能够....

表达式
The built-in assembler evaluates all expressions as 32-bit integer values. It doesn't support floating-point and string values, except string constants.

Expressions are built from expression elements and operators, and each expression has an associated expression class and expression type.
内嵌汇编计算所有三十二为整形值。他不支持浮点和字符值,字符串常量除外。
表达式使用表达式元素和操作符建立,每一个表达式都一个关联的表达式类和表达式类型。
Differences between Object Pascal and assembler expressions
Object Pascal和汇编表达式的不同:
内嵌汇编和delphi表达式最大的不同是,汇编表达式必须解决能够在编译时被计算的常量。
例如,给出如下声明:
const
  X = 10;
  Y = 20;
var
  Z: Integer;

the following is a valid statement.
下面是有效的表达式段
asm
  MOV     Z,X+Y
end;

Because both X and Y are constants, the expression X + Y is a convenient way of writing the constant 30, and the resulting instruction simply moves of the value 30 into the variable Z. But if X and Y are variables--
因为x和y都是常量,表达式x+y是一个简单方法写的常量30,并起在结果构造中简单的移动值30到变量z中。但是如果x和y是变量。

var
  X, Y: Integer;

the built-in assembler cannot compute the value of X + Y at compile time. In this case, to move the sum of X and Y into Z you would use
内嵌汇编不能再编译期计算x+y的值,在这种情况下,要移动x和y到z中,你要使用:

asm
  MOV     EAX,X
  ADD     EAX,Y
  MOV     Z,EAX
end;

In a Delphi expression, a variable reference denotes the contents of the variable. But in an assembler expression, a variable reference denotes the address of the variable. In Delphi the expression X + 4 (where X is a variable) means the contents of X plus 4, while to the built-in assembler it means the contents of the word at the address four bytes higher than the address of X. So, even though you're allowed to write
在delphi表达式中,一个变量引用表示变量的内容。但在汇编表达式中,一个变量引用表示变量的地址。在delphi表达式中x+4(变量在哪)意味着x+4的内容,相比在内嵌汇编中他意味着高于x地址的4个字节字的内容。因此,及时你允许去写

asm
  MOV     EAX,X+4
end;

this code doesn't load the value of X plus 4 into AX; instead, it loads the value of a word stored four bytes beyond X. The correct way to add 4 to the contents of X is
这个代码没有加载x加4到AX寄存器中,他加载了在x后4个字节存储的一个字的值。

asm
  MOV     EAX,X
  ADD     EAX,4
end;

表达式常量
内嵌汇编支持两种类型的常量:numberic和string常量

Numberic常量
Numeric constants must be integers, and their values must be between -2,147,483,648 and 4,294,967,295.

By default, numeric constants use decimal notation, but the built-in assembler also supports binary, octal, and hexadecimal. Binary notation is selected by writing a B after the number, octal notation by writing an O after the number, and hexadecimal notation by writing an H after the number or a $ before the number.

Numeric constants must start with one of the digits 0 through 9 or the $ character. When you write a hexadecimal constant using the H suffix, an extra zero is required in front of the number if the first significant digit is one of the digits A through F. For example, 0BAD4H and $BAD4 are hexadecimal constants, but BAD4H is an identifier because it starts with a letter.
数字常量必须是整数,而他的值必须在-2147483648到4294967295之间。
默认情况下,数字常量可以使用decimal符号,但是在内嵌汇编中也支持二进制,八进制和十六进制。二进制符号选择使用在数字后面加B,八进制符号是在数字后边加O,十六进制符号是在数字后边加H或者在数字前加$

String常量
String constants must be enclosed in single or double quotation marks. Two consecutive quotation marks of the same type as the enclosing quotation marks count as only one character. Here are some examples of string constants:
字符串常量必须使用单引号或者双引号标记,最为两个封闭引号字符只有一个同类型的连续引号。这里有些字符串常量的例子:
'Z'
'Delphi'
'Linux'
"That's all folks"
'"That''s all folks, " he siad.'
'100'
'"'
"'"
String constants of any length are allowed in DB directives, and cause allocation of a sequence of bytes containing the ASCII values of the characters in the string. In all other cases, a string constant can be no longer than four characters and denotes a numeric value which can participate in an expression. The numeric value of a string constant is calculated as

Ord(Ch1) + Ord(Ch2) shl 8 + Ord(Ch3) shl 16 + Ord(Ch4) shl 24

where Ch1 is the rightmost (last) character and Ch4 is the leftmost (first) character. If the string is shorter than four characters, the leftmost characters are assumed to be zero. The following table shows string constants and their numeric values.

String examples and their values

任意长度的字符串常量是允许使用DB指令的。并且...所有其他情况,一个字串常量不能超过4个字符并表示一个数值,可以在表达式中作为一个规则。一个字符串常量值的计算方法是:
Ord(Ch1) + Ord(Ch2) shl 8 + Ord(Ch3) shl 16 + Ord(Ch4) shl 24
ch1是最右侧(最后)一个字符,ch4是最左边(第一)个字符。如果字串比4个字符短,最左边的字符将被忽略为0,下面的表现是了字符串常量和他们的数值值。

字串示例和他们的值:
String    Value
'a'    00000061H
'ba'    00006261H
'cba'    00636261H
'dcba'    64636261H
'a '    00006120H
'   a'    20202061H
'a' * 2    000000E2H
'a'-'A'    00000020H
not 'a'    FFFFFF9EH

寄存器常量
以下为CPU保留字寄存器符号:
CPU registers
32-bit general purpose    EAX  EBX  ECX  EDX    32-bit pointer or index    ESP  EBP  ESI  EDI
16-bit general purpose    AX  BX  CX  DX    16-bit pointer or index    SP  BP  SI  DI
8-bit low registers    AL  BL  CL  DL    16-bit segment registers    CS  DS  SS  ES
32-bit segment registers    FS  GS
8-bit high registers    AH  BH  CH  DH    Coprocessor register stack    ST

When an operand consists solely of a register name, it is called a register operand. All registers can be used as register operands, and some registers can be used in other contexts.
The base registers (BX and BP) and the index registers (SI and DI) can be written within square brackets to indicate indexing. Valid base/index register combinations are [BX], [BP], [SI], [DI], [BX+SI], [BX+DI], [BP+SI], and [BP+DI]. You can also index with all the 32-bit registers--for example, [EAX+ECX], [ESP], and [ESP+EAX+5].
当一个操作数只包含一个寄存器的名称,他被称为寄存器操作符。所有的寄存器都可以使用寄存器操作数,并且有些寄存器可以使用其他内容。基地址寄存在(BX和BP)和索引寄存器(SI和DI)可以使用方括号来定位索引。有效的基地值和索引寄存器组合是[BX],[BP],[SI],[DI],[BX+SI],[BX+DI],[BP+SI]和[BP+DI]。你也可以使用所有三十二为的寄存器--如:[EAX+ECX],[ESP],和[ESP+EAX+5]

The segment registers (ES, CS, SS, DS, FS, and GS) are supported, but segments are normally not useful in 32-bit applications.
段寄存器(ES,CS,SS,DS,FS和GS)都被支持,但段寄存器通常不使用三十二位应用当中。
The symbol ST denotes the topmost register on the 8087 floating-point register stack. Each of the eight floating-point registers can be referred to using ST(X), where X is a constant between 0 and 7 indicating the distance from the top of the register stack.
符号ST表示在8087浮点寄存器栈最顶层寄存器。每8个浮点寄存器可以使用ST(X)来引用,X是0到7的常量,定位到寄存器栈最顶层的距离。

符号
The built-in assembler allows you to access almost all Delphi identifiers in assembly language expressions, including constants, types, variables, procedures, and functions. In addition, the built-in assembler implements the special symbol @Result, which corresponds to the Result variable within the body of a function. For example, the function
在汇编语言表达式中,内嵌汇编允许你使用大多数所有的Delphi标识符。包括常量,类型,变量,过程和函数。另外,内嵌汇编实现的特殊符号@Result,也也可以在函数体中得到响应。
例如函数
function Sum(X, Y: Integer): Integer;
begin
  Result := X + Y;
end;

could be written in assembly language as
写成汇编语言是:

function Sum(X, Y: Integer): Integer; stdcall;
begin
  asm
    MOV     EAX,X
    ADD     EAX,Y
    MOV     @Result,EAX
  end;
end;

he following symbols cannot be used in asm statements:

Standard procedures and functions (for example, WriteLn and Chr).
String, floating-point, and set constants (except when loading registers).
Labels that aren't declared in the current block.
The @Result symbol outside of functions.
下面的符号不能在asm段使用:
标准的过程和函数(例如:Writeln和Chr)
字串,浮点和设定常量(除了在加载寄存器的时候)
标签不能在当前块声明。
@Result符号不能用在函数的外边。
The following table summarizes the kinds of symbol that can be used in asm statements.
下表汇集了能够用于asm段的各种符号

Symbol    Value    Class    Type
Label    Address of label    Memory reference    Size of type
Constant    Value of constant    Immediate value    0
Type    0    Memory reference    Size of type
Field    Offset of field    Memory    Size of type
Variable    Address of variable or address of a pointer to the variable    Memory reference    Size of type
Procedure    Address of procedure    Memory reference    Size of type
Function    Address of function    Memory reference    Size of type
Unit    0    Immediate value    0
@Result    Result variable offset    Memory reference    Size of type

With optimizations disabled, local variables (variables declared in procedures and functions) are always allocated on the stack and accessed relative to EBP, and the value of a local variable symbol is its signed offset from EBP. The assembler automatically adds [EBP] in references to local variables. For example, given the declaration
优化选项取消,本地变量(声明在过程和函数当中)总是被定为在栈EBP,并且

var Count: Integer;

within a function or procedure, the instruction
一个函数或过程指令

MOV     EAX,Count


assembles into MOV EAX,[EBP-4].

The built-in assembler treats var parameters as a 32-bit pointers, and the size of a var parameter is always 4. The syntax for accessing a var parameter is different from that for accessing a value parameter. To access the contents of a var parameter, you must first load the 32-bit pointer and then access the location it points to. For example,
内嵌汇编把参数作为32为指针来处理,变量参数的大小永远是4。 同步处理变量参数和值参数是不同的。要处理变量参数的内容,你必须首先加载32为指针并定位他所指向的地址来处理,例如:

function Sum(var X, Y: Integer): Integer; stdcall;
begin
  asm
    MOV     EAX,X
    MOV     EAX,[EAX]
    MOV     EDX,Y
    ADD     EAX,[EDX]
    MOV     @Result,EAX
  end;
end;

Identifiers can be qualified within asm statements. For example, given the declarations
标识符可以使用汇编段来限定。例如,给定一个声明:


type
  TPoint = record
    X, Y: Integer;
  end;
  TRect = record
    A, B: TPoint;
  end;
var
  P: TPoint;
  R: TRect;

the following constructions can be used in an asm statement to access fields.
接下来的结构能够在汇编段使用来处理域。

MOV     EAX,P.X
MOV     EDX,P.Y
MOV     ECX,R.A.X
MOV     EBX,R.B.Y

A type identifier can be used to construct variables on the fly. Each of the following instructions generates the same machine code, which loads the contents of [EDX] into EAX.
A类型标识符能够用于飞行结构变量,下面结构的每一个元素都能产生相同的代码,加载[EDX]内容到EAX寄存器中。

MOV     EAX,(TRect PTR [EDX]).B.X
MOV     EAX,TRect([EDX]).B.X
MOV     EAX,TRect[EDX].B.X
MOV     EAX,[EDX].TRect.B.X

Expression classes
表达式类

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.
仅仅包含一个单独的寄存器名称的表达式是寄存器表达式。寄存器表达式的例子是AX,CL,DI和ES。作为操作数,寄存器表达式直接汇编成执行操作在CPU寄存器上。

Expressions that denote memory locations are memory references. Delphi's labels, variables, typed constants, procedures, and functions belong to this category.
展示内存定位的表达式是内存引用。delphi中的标签,变量,类型常量,过程和函数属于这一范畴。

Expressions that aren't registers and aren't associated with memory locations are immediate values. This group includes Delphi'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).
因为Start是一个立即数,第一个mov被汇编成为移动立即指令。第二个mov,被翻译成移动内存指令,cout是内存引用。第三个mov,中括号转换start为一个内存引用(在这个实例中,在数据段偏移10个字)。在第四个mov,offset操作转换count为一个立即数(数据段的偏移数)


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.
中括号和offset操作互为补充。下面的汇编段过程标识机器代码前段汇编代码的前两行。

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.
内嵌汇编允许你在抽象值上执行任何操作,但在做加法和减法重新定位值上是限制操作的。

Expression Type
表达式类型

Every built-in assembler expression has a type--or, more correctly, a size, because the assembler regards the type of an expression simply as the size of its memory location. For example, the type of an Integer variable is four, because it occupies 4 bytes. The built-in assembler performs type checking whenever possible, so in the instructions

每个内嵌汇编表达式都有一个类型,更正确的说法,一个尺寸。因为

var
  QuitFlag: Boolean;
  OutBufPtr: Word;
  ...
asm
  MOV     AL,QuitFlag
  MOV     BX,OutBufPtr
end;

the assembler checks that the size of QuitFlag is one (a byte), and that the size of OutBufPtr is two (a word). The instruction
汇编器检查QuitFlag的大小是1(1个字节),OutBufPtr的大小是2(一个字)。指令

MOV     DL,OutBufPtr

produces an error because DL is a byte-sized register and OutBufPtr is a word. The type of a memory reference can be changed through a typecast; these are correct ways of writing the previous instruction:
产生一个错误,因为DL是一个字节大小的寄存器,OutBufPtr是一个字。内存引用类型可以通过类型转来更改;有正确方法来写先前的指令。

MOV     DL,BYTE PTR OutBufPtr
MOV     DL,Byte(OutBufPtr)
MOV     DL,OutBufPtr.Byte

These MOV instructions all refer to the first (least significant) byte of the OutBufPtr variable.
这些mov质量全部指向OutBufPtr变量的第一个字节。

In some cases, a memory reference is untyped. One example is an immediate value (Buffer) enclosed in square brackets:
在某些情况下,内存引用没有被定义,方括号中的立即数的例子:

procedure Example(var Buffer);
asm
  MOV AL, [Buffer]
  MOV CX, [Buffer]
  MOV EDX, [Buffer]
end;

The built-in assembler permits these instructions, because the expression [Buffer] has no type--it just means "the contents of the location indicated by Buffer," and the type can be determined from the first operand (byte for AL, word for CX, and double-word for EDX).

In cases where the type can't be determined from another operand, the built-in assembler requires an explicit typecast. For example,

INC     BYTE PTR [ECX]
IMUL    WORD PTR [EDX]

The following table summarizes the predefined type symbols that the built-in assembler provides in addition to any currently declared Delphi types.

Predefined type symbols
预定义类型符号
Symbol    Type
BYTE    1
WORD    2
DWORD    4
QWORD    8
TBYTE    10