Ассемблер для процессоров Intel Pentium
Шрифт:
mov CX, len ; размер строки -> СХ
mov a1, ' ' ; шаблон для сравнения -> AL
next:
inc SI ; переход к адресу следующего элемента
cmp byte ptr [SI], AL ; сравнить элемент строки с пробелом
loope next ; повторять, пока не будет обнаружен символ,
; отличный от пробела,
; либо не будет достигнут
; конец строки
cmp CX, 0 ; был достигнут конец строки?
je fail ; да, строка состоит из пробелов,
; вывести соответствующее сообщение
mov DX, SI ; нет,
; поместить адрес первого символа,
; отличного от пробела, в регистр DX
show:
mov АН, 9h ; отобразить сообщения
int 21h
mov АН, lh
int 21h
mov AX, 4C00h
int 21h
fail:
lea DX, msg
jmp show
end start
end
Перейдем к анализу команды 1 oopne/1 oopnz. Отличие этой команды от loopе/1 oopz состоит в том, что цикл выполняется, пока выполняется условие ZF = 0. Обозначения loopпе и 1 oopnz являются синонимами и относятся к одной и той же команде. Пример использования команды loopпе приводится в листинге 5.4. Как и в предыдущем примере, это 16-разрядное приложение, которое выводит на экран дисплея часть строки, следующей за символом + (то есть String 2).
Листинг 5.4. Вывод на экран части строки после символа +
.model small
.data
s1 DB «String 1+String 2$»
len EQU $-s1
msg DB «Char + not found!$»
.code
start:
mov AX, @data
mov DS, AX
lea s1 , s1
dec SI
mov CX, len
mov a1, '+'
next:
inc SI
cmp byte ptr [SI], AL
loopne next
cmp CX, 0
je fail
mov DX, s1
show:
mov AH, 9h
int 21h
mov AH, lh
int 21h
mov AX, 4C00h
int 21h
fail:
lea DX, msg
jmp show
end start
end
Как видно из примеров, команда loop и ее модификации очень удобны для организации вычислительных алгоритмов, поскольку избавляют программиста от необходимости дополнительного кодирования и проверки условий. Последняя
команда, которую мы рассмотрим, является модификацией обычной команды loop, но предназначена она для работы с двойными словами. Такая команда очень полезна при разработке 32-разрядных приложений, которые в большинстве случаев оперируют двойными словами.
Эта команда обозначается как loopd, и основное ее отличие от команды loop состоит в том, что в качестве счетчика цикла используется регистр ЕСХ, содержимое которого в конце каждой итерации уменьшается на 4. Напомню, что двойное слово занимает в оперативной памяти 4 байта, а счетчик ЕСХ содержит размер области памяти в байтах. Адрес следующего обрабатываемого элемента отстоит от текущего на 4 в сторону увеличения или уменьшения, в зависимости от алгоритма задачи. Команда loopd оперирует с теми же флагами, что и loop. Должен заметить, что команда loopd не включена в ранние модели процессоров Intel.
В
Листинг 5.5. Поиск первого элемента массива, меньшего -100
.586
.model flat
option casemap: none
.data
al DD 312, -45, 91, -16, -377 ; сканируемый массив
len EQU $-al ; размер массива в байтах
.code
_loopd_ex proc
mov ECX, len ; размер массива в байтах -> ЕСХ
shr ECX, 2 ; преобразовать размер в двойные слова
lea ESI, a1 ; адрес первого элемента -> ESI
mov ЕАХ, -100 ; шаблон для сравнения -> ЕАХ
next:
cmp ЕАХ, [ESI] ; сравнить элемент массива
; с содержимым регистра ЕАХ
jge found ; число в массиве меньше -100,
; закончить программу
add ESI, 4 ; число больше -100, перейти
; к следующему элементу массива
loopd next ; следующая итерация
jmp not_found ; массив проверен, чисел меньше -100 нет
found:
mov ЕАХ, [ESI] ; значение элемента массива -> ЕАХ
jmp exit ; выйти из процедурь
not_found:
mov ЕАХ, 0 ; при неудачном поиске в регистр ЕАХ
; помещается О
exit:
ret
_loopd_ex endp
end
Исходный текст процедуры несложен и в дополнительных объяснениях не нуждается, нужно лишь помнить, что процедура оперирует двойными словами, и указывать следующий адрес на 4 больше предыдущего.
5.4. Оптимизация кода в процессорах Intel Pentium
До сих пор мы рассматривали различные варианты реализации условных переходов и ветвлений в программах безотносительно к тому, быстро или медленно будет работать тот или иной фрагмент кода. В большинстве случаев программист обычно не задумывается над производительностью работы приложения, учитывая то, что современные аппаратные средства обеспечивают довольно приличный уровень быстродействия и без специальных усилий со стороны разработчика программного обеспечения.
Однако в целом ряде случаев производительность программы выходит на первое место, а система команд процессоров Intel Pentium, особенно для последних моделей, позволяет ее повысить. В этом разделе мы рассмотрим некоторые вопросы, связанные с повышением эффективности программ.
Быстродействие программы в значительной степени определяется алгоритмом вычислений, а также количеством ветвлений и переходов. Кроме этого, большое влияние на производительность программы оказывают характер ветвлений и организация циклических вычислений там, где они необходимы.