[Delphi inline assembly Learning 1] Delphi and assembly

Source: Internet
Author: User

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.

  • * Shift operation


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.

  • * Number in Delphi


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.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.