Исходные тексты
void __cdecl c_cpy(int *src, int *dst, int n)
{
int a; int t;
if (n<1) return; // нечего копировать!
// поэлементное копирование массива
for (a=0;a<n;a++) dst[a]=src[a];
return;
}
Листинг 1 Реализация алгоритма копирования памяти на языке Си
_asm_cpy proc
PUSH ESI ; / *
PUSH EDI ; сохраняем регистры
PUSH ECX ; */
MOV ESI,[ESP+4+3*4] ; src
MOV EDI,[ESP+8+3*4] ; dst
MOV ECX,[ESP+8+4+3*4] ; n
REP MVSD ; копируем одной командой!
POP ECX ; /*
POP EDI ; восстанавливаем регистры
POP ESI ; */
ret ; выходим
_asm_cpy endp
Листинг 2 Ассемблерная реализация алгоритма копирования памяти
int __cdecl c_min(int *src, int n)
{
int a; int t;
if (n<2) return -1; // Не среди чего искать минимум!
// Присваиваем первому элементу массива статус
// "условно наименьшего"
t=src[0];
// Если такой, кто будет меньше нашего "меньшего"?
// есть да, то предать статус ему.
for(a=1;a<n;a++) if (t>src[a]) t=src[a];
return t;
}
Листинг 3 Реализация алгоритма поиска минимума на языке Си
_asm_min proc
PUSH ESI ; сохраняем
PUSH EDI ; регистры
MOV ESI,[ESP+8+4] ; src
MOV EDX,[ESP+8+8] ; n
CMP EDX,2 ; есть среди чего искать?
JB @exit ; нет элементов для поиска
MOV EAX, [ESI] ; присваиваем первому элементу
; статус "условно наименьшего"
@for: ; начало цикла
MOV EDI, [ESI] ; в EDI – очередной элемент
CMP EAX, EDI ; если кто еще меньше?
JB @next ; если нет, - следующий элемент
MOV EAX, EDI ; передать статус
@next:
ADD ESI, 4 ; перейти к следующему элементу
DEC EDX ; уменьшить счетчик цикла на 1
JNZ @for ; повторять цикл пока EDX > 0
@exit:
POP EDI ; восстанавливаем
POP ESI регистры
ret
_asm_min endp
Листинг 4 Ассемблерная реализация алгоритма поиска минимума
void __cdecl c_sort(int *src, int n)
{
int a; int t; int f;
if (n<2)
return; // Меньше двух элементов сортировать нельзя!
do{
f=0; // устанавливаем флаг сортировки в нуль
// Перебираем все элементы один за другим
for (a=1; a<n; a++)
// если следующий элемент меньше предыдущего
// меняем их местами и устанавливаем флаг
// сортировки в единицу
if (src[a-1]>src[a])
{
t=src[a-1];
src[a-1]=src[a];
src[a]=t;
f=1;
}
// повторять сортировку до тех пор, пока не дождемся
// первого "чистого" прохода, т.е. прохода без изменений
} while(f);
}
Листинг 5 Реализация алгоритма пузырьковой сортировки на языке Си
_asm_sort proc
MOV EDX,[ESP+8] ; n
CMP EDX,2 ; есть что сортировать?
JB @exit ; сортировать нечего, на выход
PUSH ESI ; /*
PUSH EBP ; сохраняем регистры
PUSH EBX ; */
@while: ; основной цикл сортировки
MOV ESI,[ESP+4+4*3] ; src
MOV EDX,[ESP+8+4*3] ; n
XOR EBP,EBP ; f := 0
@for: ; цикл перебора элементов
MOV EAX, [ESI] ; EAX := src
MOV EBX, [ESI+4] ; EBX := src+1
CMP EAX, EBX ; Сравнить EAX и EBX
JAE @next_for ; Если EAX > EBX перейти к
; следующему элементу
; иначе обменять элементы местами
MOV EBP, EBX ; взвести флаг изменений
MOV [ESI+4], EAX ; "не чистый" проход
MOV [ESI],EBX
@next_for:
ADD ESI, 4 ; src+=1;
DEC EDX ; уменьшить счетчик цикла
JNZ @for ; перебирать элементы, пока
; счетчик не равен нулю
OR EBP,EBP ; dirty-флаг взведен?
JNZ @while : сортировать пока не будет чисто
POP EBX ; /*
POP EBP ; Восстановить регистры
POP ESI ; */
@exit:
ret ; Выход
_asm_sort endp
Листинг 6 Ассемблерная реализация алгоритма пузырьковой сортировки
[1] некоторые процессоры (в частности Alpha) вообще не поддерживают констант, заставляя их ложить в память
[2] такое удаление удаляет и побочные эффекты типа деления на ноль