翻譯一半的Delphi彙編幫助

 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


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章