Главная страница
Библиотека (скачать книги)
Скачать софт
Введение в программирование
Стандарты для 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 (хотя и равны
между собой), то выполняется переход на следующие адреса в строках и
цикл сравнения повторяется.
Самая высокая скорость выполнения строковых операций достигается
обычно при копировании одной строки в другую или при перемещении
элементов строки из одной области памяти в другую. Это особенно заметно
при перемещении больших объемов данных.
Меньший выигрыш в производительности по сравнению с обычными командами
дают команды поиска определенного элемента строки. На скорость
выполнения строковых операций влияет и размерность операндов.
Мы рассмотрели только небольшую часть тех возможностей, которые предоставляет
нам язык ассемблера в плане оптимизации обработки данных.
В последующих главах мы будем использовать рассмотренный здесь материал
и продемонстрируем дополнительные возможности ассемблера для улучшения
качества программного кода.
<< Назад В начало Далее >> |
|