Вы не авторизированы! Логин:  Пароль:  Запомнить:    Зарегистрироваться
Забыл пароль
 
 
 

Ассемблер в Delphi

SVD programming - Программирование Delphi, HTML, PHP, CGI. Обзоры софта, ReactOS и многое другое...
 
Главная - Новости - Публикации - Файлы - Ссылки - Форум Обратная связь
 


Друзья сайта ::

Сайтом управляют ::

Друзья сайта ::
Delphi » Ассемблер в Delphi
Автор: ian hodger / Дата: 16:56 16.04.2006
Комментарии: Комментарии (0)
Рейтинг статьи: 0
Основное предназначение этой статьи, заполнить пробелы в оригинальной документации по borland delphi developer, при этом весь программный код, а так же теория, полность совместимы со всеми версиями delphi и object pascal.
Однако, не будем пропускать и те аспекты программирования, которые будут требовать пояснения для конкретных примеров, приведённых в этой статье.

Использование Ассемблера в Борландовком delphi
Перед тем, как начать, хотелось бы определиться с уровнем знаний, необходимых для нормального усвоения данного материала. Необходимо быть знакомым со встроенными средствами отладки в delphi. Так же необходимо иметь представление о таких терминах как тип реализации (instantiation), null pointer и распределение памяти. Если в чём-то из вышеупомянутого Вы сомневаетесь, то постарайтесь быть очень внимательны и осторожны при воплощении данного материала на практике. Кроме того, будет обсуждаться только 32-битный код, так что понадобится компилятор не ниже delphi 2.0.

Зачем использовать Ассемблер?
На мой взгляд, object pascal, это инструмент, позволяющий генерировать быстрый и эффективный код, однако использование ассемблера в некоторых случаях позволяет решать некоторые задачи более эффективно. За всю работу с delphi, я пришёл к выводу, что использование низкоуровневого кода необходимо в двух случая.

(1) Обработка большого количества данных. nb. В данный случай не входит ситуация, когда используется язык запроса данных.

(2) В высокоскоростных подпрограммах работы с дисплеем. nb. Имеется ввиду использование простых процедур на чистом паскале, но никак не внешних библиотек и directx.

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

Что такое Ассемблер?
Надеюсь, что Все читатели этой статьи имеют как минимум поверхностное представление о работе процессора. Грубо говоря, это калькулятор с большим объёмом памяти. Память, это не более чем упорядоченная последовательнось двоичных цифр. Каждая такая цифра является байтом. Каждый байт может содержать в себе значение от 0 до 255, а так же имеет свой уникальный адрес, при помощи которого процессор находит нужные значения в памяти. Процессор так же имеет набор регистров (это можно расценить как глобальные переменные). Например eax,ebx,ecx и edx, это универсальные 32-битные регистры. Это значит, что самое большое число, которое мы можем записать в регистр eax, это 2 в степени 32 минус 1, или 4294967295.

Как мы уже выяснили, процессор манипулирует значениями регистров. Машинный код операции прибавления 10 к значению регистра eax будет выглядеть следующим образом
Код:
05/0a/00/00/00


Однако, такая запись абсолютно не читабельна и, как следствие, не пригодна при отладке программы. Так вот Ассемблер, это простое представление машинных команд в более удобном виде. Теперь давайте посмотрим, как будет выглядеть прибавление 10 к eax в ассемблерном представлении:
Код:
add eax,10 {a := a + 10}


А вот так выглядит вычитаение значения ebx из eax
Код:
sub eax,ebx {a := a - b }


Чтобы сохранить значние, можно просто поместить его в другой регистр
Код:
mov eax,ecx {a := c }

или даже лучше, сохранить значение по определённому адресу в памяти
Код:
mov [1536],eax {сохраняет значение eax по адресу 1536}

и конечно же взять его от туда
Код:
mov eax,[1536]


Однако, тут есть важный момент, про который забывать не желательно. Так как регистр 32-битный(4 байта), то его значение будет записано сразу в четыре ячейки памяти 1536, 1537, 1538 и 1539.

А теперь давайте посмотрим, как компилятор преобразует действия с переменными в машинный код. Допустим у нас есть строка
Код:
count := 0;

Для компилятора это означает, что надо просто запомнить значение. Следовательно, компилятор генерирует код, который сохраняет значение в памяти по определённому адресу и следит, чтобы не произошло никаких накладок, и обзывает этот адрес как 'count'. Вот как выглядит такой код
Код:
mov eax,0
mov count,eax


Компилятор не может использовать строку типа
Код:
mov count,0


из-за того, что как минимум один параметр инструкции должен являться регистром.
Если посмотреть на строку
Код:
count := count + 1;

то её ассемблерное представление будет выглядеть как
Код:
mov eax,count
add eax,1
mov count,eax


Для переменных, тип которых отличается от целого, всё усложняется. Однако, рассмотрим эту тему немного позже, а сейчас предлагаю закрепить теорию практическими примерами.

Итак, рассмотрим первый пример. Сразу извинюсь за тривиальность, но с чего-то надо начинать.

Код:
function sum(x,y:integer):integer;
begin
result := x+y;
end;


А вот так будет выглядеть оперция сложения двух целых чисел на ассемблере:

Код:
function sum(x,y:integer):integer;
begin
asm
mov eax,x
add eax,y
mov result,eax
end;
end;


Этот код прекрасно работает, однако он не даёт нам преимущества в скорости, а так же потерялось восприятие кода. Но не стоит огорчаться, так как те немногие знания, которые Вы почерпнули из этого материала, можно использовать с большей пользой. Допустим, нам необходимо преобразовать явные значения red,green, и blue в цвета типа tcolor, подходящие для использования в delphi. Тип tcolor описан как 24-битный true colour хранящийся в формате целого числа, то есть четыре байта, старший из которых равен нулю, а далее по порядку красный, зелёный, синий.

Код:
function getcolour(red,green,blue:integer):tcolor;
begin
asm
{ecx будет содержать значение tcolor}
mov ecx,0
{начинаем с красной компоненты}
mov eax,red
{необходимо убедиться, что красный находится в диапазоне 0<=red<=255}
and eax,255
{сдвигаем значение красного в правильное положение}
shl eax,16
{выравниваем значение tcolor}
xor ecx,eax
{проделываем тоже самое с зелёным}
mov eax,green
and eax,255
shl eax,8
xor ecx,eax
{и тоже самое с синим}
mov eax,blue
and eax,255
xor ecx,eax
mov result, ecx
end;
end;

Заметьте, что я использовал несколько бинарных операций. Эти операции также определены непосредственно в object pascal.

Источник: http://www.sources.ru
Автор : ian hodger
Комментарии: Комментарии (0)

Внимание!

Друзья сайта
Голосование ::
Случайные статьи ::
Добавления в форуме ::
Новые комментарии ::
Пользователи on-line ::
0 пользователь, 135 гостей
 
Страница создана за 0.011 секунд

SQL общее время: 0.004 секунд
SQL запросов всего: 15
Администрация сайта не несет ответственности за содержание рекламных материалов, а так же за информацию размещаемой посетителями. При использовании материалов сайта ссылка на svdpro.info обязательна.

Powered by LDU 802

Рейтинг@Mail.ru
Copyright © 2005 - 2011 «SVD Programming»
Версия сайта для коммуникаторов
Обратная связь - Карта сайта