ТЕХНИКА ОПТИМИЗАЦИИ ПРОГРАММ

       

Исходные тексты


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] такое удаление удаляет и побочные эффекты типа деления на ноль


Содержание раздела