Программирование АССЕМБЛЕРОМ в Delphi

Previous  Top  Next

    
 

Автор: Александр Баранецкий

 

Каждый день множество программистов (кроме опытных) в Delphi, используя код высокого уровня, пишут свои программы. Как правило, пренебрегая таким понятием как Assembler, имеется ввиду в строенный в DELPHI. Конечно, тяжело сказать, что на голом «асе» можно сотворить великолепный шедевр имеется ввиду красота - VCL (Visual Component Library). Особенно относительно начинающих программистов, которые только начинают учить IDE. Но зато можно повысить скорость какого нибудь математического или системного алгоритма.

 

Сегодня я представляю на ваш суд статью по «асу». Скорее всего, она будет интересна начинающим программерам. Я не мастер, но сеже.

 

Программирование АССЕМБЛЕРОМ в “Delphi”

 

Для начала несколько основных команд.

MOV - предназначена для занесения в ячейку памяти значения. Например:

 

Code:

var

x: integer;

begin

Mov X, 10 // Занесение в Х значение 10 // X:=10;

Mov eax, 45 //Занесение в быстрый регистр

Mov ebx, eax //Присвоения значения одного регистра другому

Mov x.edx //Занесение в х значения edx

 

 

Первый параметр присваивающий объект, второй присеваемое значение.

 

ADD - Предназначена для прибавления к объекту значения. Значения передаются через запитаю. Например :

Code:

add eax,2

add x,76

 

 

 

 

Первый параметр принимающий объект, второй добавляемое значение.

 

SUB - Предназначена для вычитания от объекта значения. Значения передаются через запитаю. Например :

Code:

sub eax,18

Sub x,6

 

 

 

 

Первый параметр объект от которого отнимается , второй отнимаемое значение.

 

IMUL - команда умножения

IDIV - команда деления

CMP - Команда проверки

JNZ,JMP,JA - команды перехода.

 

Теперь перейдем к практическим примерам:

Code:

// 1 Функция сложения.

 

function plus(x, y: integer): integer;

asm

mov eax,x

add eax,y

end;

 

{

Функция вернет сумму «x» и «y». Сперва заносим «х» (move eax,x) потом

прибавляем к уже имеющемуся «y» (add eax,y).

}

// 2. Функция умножения

 

function Umnojenie(x, z: integer): integer;

asm

mov ebx,z

mov eax,x

imul ebx

end;

 

{

Заносим в обратном порядке «x» и «z» Отдаем команду на

умножение первого значения на второе «imul ebx ».

}

 

// 3. Функция вычитания

 

function Minus(x, y: integer): integer;

asm

sub x,y

end;

 

// Просто отнимаем одно от другого

 

// 4 Функция деления

 

function divider(x, y: integer): integer;

asm

mov ebx,y {1}

cdq {2}

idiv ebx {3}

end;

 

 

 

 

Эта функция отличается от остальных методом применения операторов. Занесение значения. 2. Предварительная обработка. 3. Деление.

 

Это были простейшие математические операторы, теперь мы рассмотрим более сложные операторы цикла и условие

 

Цикл на «асе» заключается в том что создается контрольный объект и при достижении определенного условия не происходи перехода к начальной контрольной точке отчета цикла.

Code:

procedure asm_cycle;

label

lb;

var

d: integer;

begin

asm

   mov ebx,0

   mov d,0

   lb:

   add d,1

   inc ebx

   cmp ebx,10

   jnz lb

   mov ebx,0

end;

Writeln(d);

end;

 

 

 

Метка lb нужна, чтобы назначить контрольную точку начала операторов цикла. Переменная «d:integer» для проверки результатов работы цикла. С зарезервированного слова ASM начинаем анализ. Mov edx,0 «edx» выступает как контрольный регистр в нем фиксируется количество повторений. А с самого начало он указывает с какой величины пойдет отчет Например mov edx,0 = for i := 0 to .. do, mov edx,43 = for i:=43 to ..do Мы установим его в 0 чтобы отчет шел с нуля. Переменную d мы тоже обнулим. Третья строка это метка начала после нее идут операторы цикла. Следующий оператор наш рабочий оператор. У нас он 1 но может быть множество. Inc edx добавляем в регистр 1 шаг пройденного цикла если пропустить то цикл будет идти вечно. cmp ebx,10 Один из основных операторов он проверяет не достиг ли цикл верхний предел. Проверка идет в самом конце. Если вернет FALSE то срабатывает следующий оператор перехода на метку т.е в начало цикла и все повторяется до тех пор пока cmp не вернет TRUE в следствии чего не сработает оператор перехода JNZ. Последними операторами обнуляем счетчик и показываем результат.

 

Условный оператор IF..THEN..ELSE.

Code:

procedure if_sample(x: integer);

var

res: integer;

label

exit, lb;

begin

asm

   cmp x,0

   jnz lb

   mov res,45

   jmp exit

   lb:mov res,0

   exit: mov eax,0

end;

Writeln(res);

end;

 

 

 

На PASCAL этот оператор пишется так if x = 0 then x:=45 else x:=0; Сначала идет проверка не равен ли х нулю если не равен то переход на метку ld, На которой оператор обнуления. А если равен, то оператор перехода на ld не срабатывает. Срабатывает mov res,45. После которого состоится переход на метку EXIT. В «асе» желательно прописывать свою метку (у нас EXIT), которая по необходимости выйдет и процедуры.

 

И последние. Вызов внешней процедуры. Допустим, надо вызвать внешнюю процедуру.

 

 

procedure call_s(x, d: integer; bol: boolean);

Для вызова внешних модулей применяется метод CALL.

Code:

procedure call_sample;

asm

mov eax,4

mov edx,34

mov cl,0

call call_s

end;

 

 

 

Сперва передаются параметры последовательно а потом сам вызов.

 

На этом мой маленький туториал окончен. Все примеры вы найдете в приложенном файле pr_asm. Это маленькое консольное приложение, в котором представлены все примеры с комментариями.

 

P.S. Я не мастер в «асе», и эта статья не сделает вас гениями она лишь призвана показать некоторые стандартные методы «паса» интерпретированные в «ас». Мастера «аса» не смейтесь надо мной сильно, так как я уже сказал, что я не мастер, я просто энтузиаст в «асе».

 

В следующей статье я продолжу описание более продвинутых операторов и методов а также попробуем написать маленькое «ас» приложение.

©Drkb::00688

http://delphiworld.narod.ru/

DelphiWorld 6.0