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

=== Программирование АССЕМБЛЕРОМ в Delphi ===
Каждый день множество программистов (кроме опытных) в Delphi, используя код высокого уровня, пишут свои программы. Как правило, пренебрегая таким понятием как Assembler, имеется ввиду в строенный в DELPHI. Конечно, тяжело сказать, что на голом «асе» можно сотворить великолепный шедевр имеется ввиду красота - VCL (Visual Component Library). Особенно относительно начинающих программистов, которые только начинают учить IDE. Но зато можно повысить скорость какого нибудь математического или системного алгоритма. 
Сегодня я представляю на ваш суд статью по «асу». Скорее всего, она будет интересна начинающим программерам. Я не мастер, но все же. 
Программирование АССЕМБЛЕРОМ в “Delphi” 
Для начала несколько основных команд. 
MOV - предназначена для занесения в ячейку памяти значения. Например: 
var
 x: integer;
begin
 Mov X, 10 // Занесение в Х значение 10 // X := 10;
 Mov eax, 45 // Занесение в быстрый регистр
 Mov ebx, eax // Присвоения значения одного регистра другому
 Mov x.edx // Занесение в х значения edx
Первый параметр присваивающий объект, второй присваемое значение. 
ADD - Предназначена для прибавления к объекту значения. Значения передаются через запятую. Например: 
add eax, 2
add x, 76 
Первый параметр принимающий объект, второй добавляемое значение. 
SUB - Предназначена для вычитания от объекта значения. Значения передаются через запятую. Например: 
sub eax, 18
Sub x, 6 
Первый параметр объект от которого отнимается , второй отнимаемое значение. 
IMUL - команда умножения
IDIV - команда деления
CMP - Команда проверки
JNZ, JMP, JA - команды перехода. 
Теперь перейдем к практическим примерам: 
// 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;
Эта функция отличается от остальных методом применения операторов.
# Занесение значения.
# Предварительная обработка.
# Деление. 
Это были простейшие математические операторы, теперь мы рассмотрим более сложные операторы цикла и условие 
Цикл на «асе» заключается в том что создается контрольный объект и при достижении определенного условия не происходит перехода к начальной контрольной точке отчета цикла. 
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. 
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. 
procedure call_sample;
asm
 mov eax, 4
 mov edx, 34
 mov cl, 0
 call call_s
end;
Сперва передаются параметры последовательно а потом сам вызов. 
На этом мой маленький туториал окончен. Все примеры вы найдете в приложенном файле pr_asm. Это маленькое консольное приложение, в котором представлены все примеры с комментариями. 
P.S. Я не мастер в «асе», и эта статья не сделает вас гениями она лишь призвана показать некоторые стандартные методы «паса» интерпретированные в «ас». Мастера «аса» не смейтесь надо мной сильно, так как я уже сказал, что я не мастер, я просто энтузиаст в «асе». 
В следующей статье я продолжу описание более продвинутых операторов и методов а также попробуем написать маленькое «ас» приложение. 
Source: http://delphiworld.narod.ru
ID: 00688