Обучающие курсы:

Обучение профессии "Разработчик C#" + стажировка в Mail.ru
Обучение профессии "Разработчик Python" + трудоустройство
Обучение профессии "Веб-разработчик" + стажировка в Mail.ru


Главная страница
Библиотека (скачать книги)
Скачать софт
Введение в программирование
Стандарты для C++
Уроки по C#
Уроки по Python
HTML
Веб-дизайн
Ассемблер в среде Windows
ActiveX
Javascript
Общее о Линукс
Линукс - подробно
Линукс - новое
Delphi
Паскаль для начинающих
Турбопаскаль
Новости
Партнеры
Наши предложения
Архив новостей





Перед началом преобразования загружаем в регистр E S I адрес строки, а в регистр ЕСХ — ее размер. Поскольку мы имеем дело с литерами, то анализ выполняется для символов ' а' - z, не затрагивая остальные. Сам алгоритм преобразования реализован в следующем фрагменте программного кода:
next:
mov AL, BYTE PTR [ESI]
cmp AL, 'a'
jb next addr
cmp AL, 'z'
ja next addr
and AL, Odfh
mov BYTE PTR [ESI], AL
next addr
inc ESI
loop next

Чтобы у читателя не сложилось впечатление, будто операции со строками можно эффективно выполнять только строковыми командами, приведем пример программы, где они вообще не используются. Операции над строками можно успешно выполнять и при помощи обычных команд ассемблера. Исходный текст консольного приложения на Delphi демонстрирует такой подход. В этой программе (листинг 2.38) выполняется сравнение двух строк и результат операции выводится на экран дисплея.
Листинг 2.38. Программа на Delphi, выполняющая сравнение двух строк с помощью обычных команд ассемблера
program cspas;
{$APPTYPE CONSOLE}
uses
SysUtils;
var
si, s2: PChar;
flag: Boolean;
function cmpstring: Boolean; assembler;
asm
mov ESI, DWORD PTR si
mov EDI, DWORD PTR s2
@again:
mov AL, BYTE PTR [ESI]
mov DL, BYTE PTR [EDI]
push EAX
push EDX
xor AL, DL
pop EDX
pop EAX
jz @streq
jmp @strnot eq
@streq:
test AL, DL
jz @succ
inc ESI
inc EDI
jmp @again
@strnot _eq:
mov EAX, 0
jmp @quit
@succ: -
mov EAX, 1
@quit:
end;

begin
{ TODO -oUser -cConsole Main : Insert code here }
si := 'STRING'#0;
s2 := 'STRING'#0;
WriteLn('si: ', si);
WriteLn('s2: s2);
Flag- := cmpstring;
if flag then
WriteLn('Strings are equal !')
else
WriteLn('Strings are not equal ! ' ) ;
ReadLn;
end.

Процедура cmpstring в самом начале загружает адрес строки-источника в регистр E S I и адрес строки-приемника в регистр E D I . Процедура сравнивает строки с завершающим нулем.

Элементы строк помещаются в регистры AL И DL, которые сравнивают их содержимое:
mov AL, BYTE PTR [ESI]
mov DL, BYTE PTR [EDI]
push EAX
push EDX
xor AL, DL
pop EDX
pop EAX
jz @streq
jmp @strnot_eq

Если символы не равны, то происходит выход из процедуры с возвратом 0 в основную программу. Если символы равны, то процедура проверяет их на равенство 0 (команда перехода jz @streq):
@streq:
test AL, DL
jz @succ
inc ESI
inc EDI
jmp @again

Если элементы равны 0, то достигнут конец строки и сравнение прошло успешно, т. е. строки равны. В этом случае процедура возвращает в основную программу значение 1. Если же элементы не равны 0 (хотя и равны между собой), то выполняется переход на следующие адреса в строках и цикл сравнения повторяется.
Самая высокая скорость выполнения строковых операций достигается обычно при копировании одной строки в другую или при перемещении элементов строки из одной области памяти в другую. Это особенно заметно при перемещении больших объемов данных.
Меньший выигрыш в производительности по сравнению с обычными командами дают команды поиска определенного элемента строки. На скорость выполнения строковых операций влияет и размерность операндов. Мы рассмотрели только небольшую часть тех возможностей, которые предоставляет нам язык ассемблера в плане оптимизации обработки данных.

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


 
 
 

Библиотека программиста. 2009.
Администратор: admin@programmer-lib.ru