I always think that Delphi functions are not inferior to C ++ in that it provides a wide range of controls and classes, all APIs, and embedded compilation. Recently, when my younger brother used Delphi to write the C version of Huffman compression, he "studied" Delphi's bit operations and Embedded Assembly. Using embedded assembly, We can get efficient program code, complete some underlying functions not provided by Delphi. I will share my "research" with you ".
1. Delphi bit operations
Every friend who learns C will be told that C is an "Intermediate Language", and its bit operations are very convenient, while Pascal's stream is only applicable to teaching. But Delphi provides a set of bit operations, so don't look at Delphi with the past attitude towards Pascal.
- * Logical operations by bit:
In DelphiAND, OR, NOTThey can be used not only for logical expressions, but also for operands;
And: bitwise AND, for example, 1 and 2. The result is 0.
Or: bitwise or, for example, 1 or 2. The result is 3.
Not: bitwise inverse: If not 1, the result is-2 for the signed number and 65534 for the unsigned number.
In additionBy bit or XOR: For example, the result of 1 XOR 2 is 3.
Delphi provides SHL and SHR shift left and right:
For example, 2 shr1 indicates 2 shifts one digit right by bit and the result is 1.
Since a bit operation involves the number type, it must be a signed number (the first bit uses 0 and 1 to indicate positive and negative) or an unsigned number.
In Delphi, memory int (8 bits), smallint (16 bits), longint (32 bits), INTEGER (32 bits), and int64 (64 bits) are signed numbers; byte (8 bits), word (16 bits), and longword (32 bits) are unsigned. They can be forcibly converted like C. For example, if-1 of the smallint type is converted to the word type, it is 65535. The conversion method is word (-1 ).
How can this problem be solved? ^_^! What is not enough ......!? There is another trick in Delphi. Let's pick it up ......
2. Embedded compilation of Delphi
Delphi provides support for almost all Common Assembly commands: mov, je, JMP, CMP, SHL, SHR, Sal, SAR, Pop, push, hlt ...... Check it by yourself. Int can also be identified, but you can leave it alone for illegal operations or crashes (in the earliest Windows 95, Delphi 3 seems to be able to properly run and interrupt, but Windows 95 OEM and Windows 98 are not correct, it is probably a 16-bit module problem, but it is still unclear ).
* Embedded Assembly format
Delphi uses ASM ...... End to mark Assembly Statements
For example, ASM
MoV Al, 1
MoV BL, Al
End;
* Operable registers
Delphi can manage the following registers using assembler:
32-bit register eax EBX ECx edX ESP EBP ESI EDI
16-bit register ax bx cx dx sp bp Si Di
8-bit register Al BL Cl DL Ah BH ch DH
16-bit register cs ds ss es
And coprocessor register stack St
* Work Before assembly
The assembler teacher repeatedly stressed that the register should be saved in the Assembly field (the register status before use should be saved, and the stack should be pushed and Pop up from the stack ), however, all this is unnecessary for Embedded compilation of Delphi (unless you want to use Push and Pop), Because Delphi has already helped you, so you don't have to worry about losing data.
* Use of Delphi Embedded Assembly
1. Use assembly in the general function Process
Assembler segments can be nested in other processes: for example:
Procedure TForm1.Button1Click (Sender: TObject );
Var I: smallint;
Begin
I: = 1;
Asm
Mov ax, I
Sal ax, 1
Mov & I, ax
End;
Showmessage (inttostr (I ));
End;
This section shifts the 16-bit variable I to the left, and then uses the Mov & I, ax statements to return the value from the address where the I variable is located. The value of I is 2.
2. Independent assembler segments
The assembler segment can also be written as a function or process separately. This involvesPassing parameters and returning results. First, Delphi has a convention for returning functions:
That is, integer data: 8 bits are returned by AL, 16 bits are returned by AX, 32 bits are returned by EAX, and real-time data is returned by ST (0 ).
Pointer: returned with EAX
Long String: Use EAX to return its address
Variable: available @ Result returned
For example, a summation function using an assembly
Function _ Sum (X, Y: Integer): Integer;
Asm
Mov eax, X // put the 32-bit number into EAX
Add eax, Y // perform addition operations
MOV @ Result, EAX // returns X + Y
End;
An example of a function that converts characters into uppercase letters
Function _ UpCase (ch: Char): Char;
Asm
Cmp al, 'A'
JB @ exit
Cmp al, 'Z'
JA @ exit
Sub al, 'a'-'A'
@ Exit:
End;
It is worth noting that in the second example, the statement of the parameter is not put into the register as in the first one, because in Delphi, the Byte (Char) type is put in AL by default, no Mov statement is required, but such a function cannot be a member of the class. Otherwise, an error occurs.
3. Call other processes in assembly
The Call statement in an Assembly statement can be used to Call other processes. It can be either another assembly program segment or a standard process in Delphi:
For example, if you create a new form and add a button to it, write the following code in the Click event:
Procedure TForm1.Button1Click (Sender: TObject );
Begin
Showmessage ('OK ');
End;
Write another process _ X
Function TForm1. _ x (var I: smallint): integer;
Asm
Call button1click
End;
The message box is displayed after the execution of _ x.
* Assembly debugging
Well, if you have compiled the program, you have to use debugging tools, such as variable tracking, breakpoint, stack viewing ...... You can also use the Debug Windows CPU window tracking in the View menu for compilation.
Code:
Program Project1;
{$ Apptype console}
Uses
SysUtils;
Var
A, B, c, d: Word;
BYTE1: Byte;
Word1: Word;
Int1: Integer;
(*------------------------------------------------------------------------*)
Function add2value (x1: Integer; x2: Integer): Integer; (* functions compiled by sink *)
Asm
Mov eax, x1;
Add eax, x2;
Mov @ result, eax; (* return value: @ result *)
End;
(*------------------------------------------------------------------------*)
Begin
Try
{TODO-oUser-cConsole Main: Insert code here}
Asm
Mov a, 'a ';
Mov B, 'B ';
Mov c, 'C ';
Mov d, 'd ';
End;
Writeln (chr (a) + chr (B) + chr (c) + chr (d ));
BYTE1: = $ FF;
Writeln (BYTE1 and $ 0F );
BYTE1: = $ 0F;
Writeln (BYTE1 or $ F0 );
Word1: = 1;
Asm
Mov ax, word1
Sal ax, 1 (* shifts 1 bit left *)
Mov & word1, ax
End;
Writeln ('I =' + IntToStr (word1 ));
Int1: = add2value (12, 32 );
Writeln (int1 );
Except
On E: Exception do
Writeln (E. ClassName, ':', E. Message );
End;
Readln;
End.