Встроенный ассемблер имеет свои преимущества, но обладает меньшей производительностью и ограничен возможностями среды разработки. Если вы используете старую версию Delphi, то в ней не будет поддержки современных инструкций процессоров 3D Now или SSE. Но это поправимо, если использовать внешний ассемблер. В этом случае вы пишете модуль полностью на ассемблере, компилируете его и только подключаете получившийся в результате объектный файл к своему проекту.

Недостаток этого способа в том, что процедуру или функцию приходится полностью писать на языке ассемблер. Если при встроенном варианте можно было делать только вставки, то в данном случае операторы Delphi недопустимы, потому что компилятор ассемблера не сможет собрать такой код.

Давайте рассмотрим пример использования внешних процедур, написанных на ассемблере. Создайте файл WordCountasm со следующим содержимым:

.386
.model f1 at.STDCALL .code
PUBLIC WordCount
WordCount PROC
push ds
mov EAX, 10
pop ds
ret
ENDP

ENDS end Здесь объявлена открытая процедура WordCount, в которой выполняются следующие действия:

1. push ds - сохранение содержимого регистра ds (указатель в сегменте данных). В примере это не обязательно, потому что данные не используются, но я вставил эту операцию, чтобы при написании собственных процедур на языке ассемблер вы не забывали сохранять этот регистр.

2. mov ЕАХ, 10 - в регистр ЕАХ помещается значение 10. Вам уже известно, что через этот регистр функции возвращают свои значения. Внешние функции не являются исключением.

3. pop ds - восстановление регистра ds перед выходом.

4. ret - выход из процедуры.

При компиляции этого примера я использовал TASM 32 фирмы Borland. Для этого в командной строке нужно ввести команду:

Tasm32. exe WordCount .asm •

После компиляции образуется файл WordCountobj, который будет подключаться к проекту в Delphi. Поместите этот файл в папку, где расположен соответствующий проект.

Теперь посмотрим, как в Delphi можно использовать функцию WordCount из файла WordCountobj, созданного на ассемблере. Создайте новый проект в Delphi. Чтобы компилятор знал, где искать функцию WordCount и как она выглядит, ее нужно описать. Исходный код формы с необходимым описанием приведен в листинге 2.8.

Листинг 2.8. Описание внешней функции, написанной на ассемблере

unit MainUnit:
interface uses
Windows, Messages. SysUtils, Variants. Classes, Graphics, Controls. Forms. Dialogs, StdCtrls;
function wordcount: integer;
type TExtAsmForm = class(TForm) Buttonl- TButton;
procedure ButtonlClick(Sender. TObject): private {Private declarations} public
{Public declarations}
end;
var
ExtAsmForm: TExtAsmForm;
implementation function wordcount;
external {$L WordCount.obj} {$R *.dfm} end.

Перед разделом type находится описание функции wordcount: function wordcount: integer:

Теперь ее можно использовать в проекте, указав компилятору, где искать функцию. Для этого в разделе implementation приведены две строки:

function wordcount; external; {$L WordCount obj} В первой строке мы сообщаем компилятору, что функция внешняя (external), во второй строке подключается файл WordCountobj. Подключение файла *.obj похоже на подключение ресурсного файла *.dfm, только здесь используется ключ $1_ или $LINK (подключение).

На первый взгляд описание сложное, но это в том случае, когда необходимая функция должна использоваться до раздела implementation. Просто подключить файл и описать внешнюю функцию можно только в этом разделе, а если она должна использоваться раньше, то компилятор выдаст ошибку. Чтобы этих ошибок не было, приходится делать короткое описание до раздела type.

Если функция не используется в разделе type, то достаточно в разделе implementation написать следующие строки:

function wordcount: Integer; external: {$L WordCount obj} В первой строке мы описываем функцию и сразу же указываем, что она внешняя.

Теперь внешняя функция может использоваться как "родная". Посмотрите на пример ее использования:

procedure TExtAsmForm.ButtonlClick(Sender: TObject): var
i: Integer;
begin
i .= wordcountO: ShowMessage(IntToStr(i)), end;

ПРИМЕЧАНИЕ -

Исходный код рассмотренного здесь примера находится на компакт-диске в каталоге Sources\ch02\ExternalAsm.

С помощью ключа {$L Имя файла} можно подключать любые объектные файлы, откомпилированные не только на языке ассемблер, но и на языке C/C++. При подключении файлов, созданных на С, проблем не будет. При использовании объектной модели С++ могут возникнуть некоторые трудности, особенно при использовании MFC.

2.14.1. Встроенный ассемблер || Оглавление || 2.15. Сокращение цепочек


Delphi в шутку и всерьез: что умеют хакеры



Новости за месяц

  • Декабрь
    2021
  • Пн
  • Вт
  • Ср
  • Чт
  • Пт
  • Сб
  • Вс
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31