Конспект лекций по курсу Системное программирвание для специальности Информатика Лекция 1




НазваниеКонспект лекций по курсу Системное программирвание для специальности Информатика Лекция 1
страница7/41
Дата публикации03.03.2013
Размер5.22 Mb.
ТипКонспект
uchebilka.ru > Информатика > Конспект
1   2   3   4   5   6   7   8   9   10   ...   41

Листинг 4. Вывод на экран части строки после символа +

.model small
.data

si DB "String 1+String 2$"

len EQU $-sl

msg DB "Char + not found!$"
.code
start:

mov AX. @data

mov DS. AX

lea SI. si

dec SI

mov CX. len

mov AL. ' + '
next:

inc SI

emp byte ptr [SI]. AL

loopne next

emp CX. 0

je fail

mov DX. SI
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 в сторону увеличения или уменьшения, в зависимости от алгоритма задачи. Команда 1 oopd оперирует с теми же флагами, что и 1оор. Должен заметить, что команда loopd не включена в ранние модели процессоров Intel.

В качестве примера выполнения цикла с использованием команды loopd приведу 32-разрядную процедуру, выполняющую поиск в массиве целых чисел первого элемента, меньшего -100. В случае удачного поиска процедура возвращает значение этого элемента в регистре ЕАХ, в случае неудачи - 0 в этом же регистре. Исходный текст процедуры (она называется Joopdex) приведен в листинге
Листинг Поиск первого элемента массива, меньшего -100

.5В6

.model flat

option casemap: none

.data

al DD 312. -4 91. -16. -377 : сканируемый массив
len EQU $-al : размер массива в байтах

.code

_loopd_ex proc

mov ECX. len : размер массива в байтах -> ЕСХ

shr ECX. 2 : преобразовать размер в двойные слова

lea ESI. al : адрес первого элемента -> 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 : при неудачном поиске в регистр ЕАХ

: помещается 0 exit:

ret

_loopd_ex endp

end

Исходный текст процедуры несложен и в дополнительных объяснениях не нуждается, нужно лишь помнить, что процедура оперирует двойными словами, и указывать следующий адрес на 4 больше предыдущего.
^ 4. Оптимизация кода в процессорах Intel Pentium
До сих пор мы рассматривали различные варианты реализации условных переходов и ветвлений в программах безотносительно к тому, быстро или медленно будет работать тот или иной фрагмент кода. В большинстве случаев программист обычно не задумывается над производительностью работы приложения, учитывая то, что современные аппаратные средства обеспечивают довольно приличный уровень быстродействия и без специальных усилий со стороны разработчика программного обеспечения.

Однако в целом ряде случаев производительность программы выходит на первое место, а система команд процессоров Intel Pentium, особенно для последних моделей, позволяет ее повысить. В этом разделе мы рассмотрим некоторые вопросы, связанные с повышением эффективности программ.

Быстродействие программы в значительной степени определяется алгоритмом вычислений, а также количеством ветвлений и переходов. Кроме этого, большое влияние на производительность программы оказывают характер ветвлений и организация циклических вычислений там, где они необходимы.

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

Поскольку избежать ветвлений и переходов в программах вряд ли когда-нибудь удастся, то можно, по крайней мере, уменьшить их количество или оптимизировать сами ветвления. Разработчики фирмы Intel включили в систему команд процессоров Pentium ряд новых команд, предназначенных для оптимизации переходов в программах. Лучше всего показать работу таких команд на примерах и одновременно изучить их синтаксис.

Для повышения производительности программ фирма Intel включила в новые поколения процессоров, начиная с Pentium II, ряд команд, позволяющих эффективно управлять ветвлениями программы. К таким командам относятся команды setCC, cmovCC и fcmovCC, где СС - одно из условий (е, nе, lе и т. д.).

Остановимся на синтаксисе этих команд и начнем с команд setCC. Вот их формат:
setCC reg8

setCC mem8
Здесь setCC - одна из следующих команд: sete/setz, setl/setnge и т. д., a reg8/ тет8 - единственный операнд команды, представляющий собой 8-разрядный регистр, например AL, АН, BL и т. д., или байт памяти. Если заданное в команде условие выполнено, то в операнд помещается значение 1, если ложно - 0. Команды set CC анализируют соответствующие флаги, установленные предыдущими ассемблерными инструкциями.

Проиллюстрируем сказанное примером:
cmp AL. О sete BL
Если после выполнения команды стр обнаружено равенство нулю содержимого регистра AL, то флаг ZF будет установлен в 1. Следующая команда sete анализирует состояние этого флага и помещает в регистр BL значение 1. Если бы в AL содержалось число, отличное от нуля, то в регистр BL было бы записано значение 0.

Перечень команд set CC приведен в табл. 4.
Таблица 4. Команды setCC


Мнемоника

Описание

^ Проверяемые флаги

SETAE/SETNB

Установить, если выше или равно/не ниже

CF

SETE/SETZ

Установить, если равно/нуль

ZF

SETNE/SETNZ

Установить, если не равно/не нуль

ZF

SETB/SETNAE

Установить, если ниже/не выше или равно

CF

SETBE/SETNA

Установить, если ниже или равно/не выше

CF, ZF

SEiySETNGE

Установить, если меньше/не больше или равно

SF, OF

SETGE/SETNL

Установить, если больше или равно/не меньше

SF, OF

SETG/SETNLE

Установить, если больше/не меньше или равно

ZF, SF, OF

SETS

Установить, если SF = 1

SF

SETNS

Установить, если SF = 0

SF

SETC

Установить, если CF = 1

CF

SETNC

Установить, если CF = 0

CF

SETO

Установить, если OF = 1

OF

SETNO

Установить, если OF = 0

OF

SETP/SETPE

Установить, если PF = 1

PF

SETNP/SETPO

Установить, если PF = 0

PF


Команды set CC очень удобны при организации вычислений по условию. При этом можно избавиться от ненужных команд переходов, что дает выигрыш в быстродействии. Рассмотрим следующий пример. Пусть в массиве целых чисел требуется найти первое число, лежащее между 50 и 100. Эту задачу можно решить с помощью процедуры find_num, исходный текст которой показан в листинге 6.

В этой процедуре просматривается массив целых чисел al, адрес которого находится в регистре ESI. Для поиска нужного элемента используется обычный алгоритм, в котором каждый элемент массива проверяется дважды: является ли он меньшим или равным числу 100 (команды cmp dword ptr [ESI], 100 и jle nextl), а также большим или равным 50 (команды cmp dword ptr [ESI]. 50 и jge found). Применение нескольких команд set CC позволяет уменьшить число ветвлений программы.
Листинг 6. Поиск первого элемента массива, находящегося в диапазоне 50-100

.686

.model flat

option caseraap: none

.data

al DD 34. -53. 88. 13. 67

len EQU $-al

.code

findjium proc

lea ESI. al : адрес массива -> ESI

mov ECX. Len : размер массива в байтах -> ЕСХ

shr ECX. 2 : преобразовать в количество двойных

: слов

next:

cmp dword ptr [ESI]. 100 : элемент массива меньше или

: равен 100?

jle nextl : да. выполним следующую проверку

jmp next_addr : число больше 100. перейти

: к следующему адресу

nextl:

cmp dword ptr [ESI]. 50 : элемент массива больше или

: равен 50?

jge found : да. элемент обнаружен, поместить его

: в регистр ЕАХ и выйти из процедуры
next_addr : перейти к следующему элементу массива

add ESI. 4

dec ECX : декремент счетчика

jnz next : если содержимое ЕСХ не равно 0.

: перейти к следующей итерации

mov ЕАХ. 0 : цикл завершен, требуемый элемент

: отсутствует, помещаем в ЕАХ значение 0

jmp exit

found:

mov ЕАХ. [ESI] : найденный элемент -> ЕАХ exit:

ret

find_num endp

end
В листинге 7 представлен модифицированный вариант этой же процедуры, в которой в той или иной форме используются команды setCC.

Листинг 7. Модифицированный с использованием команд setCC вариант листинга 6

.686

.model flat

option casemap: none

.data

al DD 34. -53. 88. 13. 67

len EQU $-al

g50 DB ? : вспомогательные переменные

1100 DB ?

.code

find_num proc
lea ESI. al : адрес массива -> ESI

mov ECX. len : размер массива в байтах -> ЕСХ

shr ECX. 2 : преобразовать в количество двойных слов

next:

cmp dword ptr [ESI]. 50 : элемент массива больше или

: равен 50?
setge g50 : если да. установить переменную д50 в 1,

: иначе установить д50 в О
cmp dword ptr [ESI]. 100 : элемент массива меньше или

: равен 100?
setle 1100 : если да. установить переменную 1100 в 1,

: иначе установить 1100 в 0

mov AL, g50 : сравнить g50 и 1100

cmp AL. 1100
je found : если переменные равны, элемент обнаружен

: и поиск заканчивается
add ESI. 4 : нет. g50 не равен 1100. продолжить поиск

dec ECX
jnz next
mov EAX. 0 : цикл закончен, нужный элемент не найден.

: помещаем в регистр ЕАХ значение 0

jmp exit

found:

mov EAX. [ESI]: значение обнаруженного элемента -> EAX exit:

ret

find_num endp

end
В исходном тексте изменения выделены жирным шрифтом. Смысл изменений достаточно очевиден, замечу лишь, что нам удалось избавиться от двух команд условных переходов и сделать программный код более линейным. При указанных значениях элементов массива по завершении процедуры регистр ЕАХ будет содержать число 88.

Следующая группа команд, которую мы рассмотрим, включает команды стоvCC. Формат этой команды выглядит так:
cmovCC src. Dst
Здесь СС - одно из условий (е, ne, nz, 1 е и т. д.), src может быть 16- или 32-разрядным регистром, a dst - 16- или 32-разрядным регистром или ячейкой памяти. Команда проверяет условие и, если оно выполняется, копирует содержимое dst в src. Если условие не выполняется, операнд src остается без изменений. Небольшой пример поможет лучше понять способ использования команд cmov CC:
.data

opl DW ? .code

cmp AX. opl cmovge AX. Opl
Если содержимое регистра АХ больше или равно переменной opl, то opl копируется в АХ. Если же содержимое АХ меньше opl, то оба операнда остаются неизменными.

Команда cmovCC весьма полезна при разработке быстрых алгоритмов и оптимизации ветвлений. Перед применением команды cmovCC необходимо проверить, поддерживается ли она процессором, что легко сделать с помощью команды cpuid.

Рассмотрим еще один пример программы, в которой присутствуют команды условных переходов, и попробуем ее усовершенствовать. Пусть требуется определить большее из двух целых чисел. Если использовать обычные команды ассемблера, то этот алгоритм можно реализовать с помощью следующей последовательности инструкций:
.data

numl ::DD 12

тшй? ::dd и .code

:clc

ttov EAX. numl

fflov EDX. ruim2

imp EAX. EDX

jg numl_g num2

Kiiov EBX. EDX

jmp exit nimil::g_num2:

tov EBX. EAX exit:
Этот код сравнивает два целых числа - numl и num2, помещая большее из них в регистр ЕВХ. Здесь присутствует команда условного перехода jg, выполняющая переход на другую ветвь программного кода, если numl больше num2. Для модификации программного кода воспользуемся командой cmovl. Новый вариант исходного текста программы выглядит так:
.data

numl :i)D 12

гний ::dd и .code

-tnov ЕЛХ. numl

-mov EDX. nuiitf

стар ЕЛХ. EDX

cmovl EAX. EDX

mov EBX. EAX
Проанализируем программный код. В регистр EAX помещается первое число (numl), а в EDX - второе (num2). После выполнения показанной ниже команды сравнения будут установлены соответствующие флаги:
cmp EAX. EDX
Следующая команда помещает в регистр ЕАХ содержимое EDX, если число в EDX больше числа в ЕАХ, и оставляет содержимое ЕАХ без изменения, если число в ЕАХ больше числа в EDX:
cmovl EAX. EDX
Наконец, содержимое регистра ЕАХ помещается в регистр ЕВХ. Из этого фрагмента видно, что ветвлений и переходов нет. Перед использованием команды стоvCC необходимо проверить, поддерживается ли она данным типом процессора. Такую проверку можно выполнить с помощью команды cpuid.

Рассмотрим еще один пример. Пусть требуется найти модуль (абсолютное значение) числа. Используя обычную команду условного перехода jge, можно сделать это с помощью следующего программного кода:
.data

numl DD -18 .code

mov EAX. numl

emp EAX. 0

jge exit

neg EAX
exit:
Как видно из исходного текста, после команды сmр программный код разветвляется. Этого можно легко избежать, если использовать команду cmovl. Более быстродействующий код выглядит так:
.data

numl DD 18 .code

mov EAX. numl

mov EDX. EAX

neg EDX

emp EAX, 0

cmovl EAX. EDX
В нашем последнем примере представлен окончательный вариант процедуры findjium, в которой используются команды set CC и cmov CC (листинг 8).

Ранее мы уже достаточно подробно анализировали исходный текст процедуры findnum, поэтому остановимся лишь на последних изменениях (они выделены жирным шрифтом). Как видно из листинга, в случае равенства переменных д50 и 1100 команда cmove EAX, [ESI] копирует искомое значение в регистр ЕАХ. Следующая инструкция je exit передает управление либо на выход процедуры (флаг ZF = 1), либо следующей команде (в данном случае add ESI. 4). Команда cmove EAX, [ESI] не влияет на состояние флагов, поэтому инструкция je exit, фактически, анализирует флаги, установленные командой emp AL. 1100. Как видите, в модифицированном варианте процедуры осталось всего две команды условных переходов.

Более-менее сложная программа, помимо условных и безусловных переходов, может содержать один или несколько вычислительных циклов. Вычисления или другие операции, выполняющиеся циклически, могут повторяться от нескольких десятков до сотен миллионов раз, создавая ощутимую нагрузку на память и процессор. Правильная организация циклов помогает не только повысить производительность программы в целом, но и снизить потребление ресурсов. Сейчас мы проанализируем, каким образом можно повысить производительность программы или процедуры на ассемблере за счет оптимизации циклических вычислений.
1   2   3   4   5   6   7   8   9   10   ...   41

Похожие:

Конспект лекций по курсу Системное программирвание для специальности Информатика Лекция 1 iconКонспект лекций для студентов заочной формы обучения направления 080201 (Информатика)
Предлагаемый конспект лекций представляет собой пособие по предмету “Теория информации”, который читается в Сумском государственном...

Конспект лекций по курсу Системное программирвание для специальности Информатика Лекция 1 iconКонспект лекций 2007 Экология. Конспект лекций. Для студентов специальностей...
Экология. Конспект лекций. Для студентов специальностей 080201 «Информатика», 090220 «Оборудование химических производств и предприятий...

Конспект лекций по курсу Системное программирвание для специальности Информатика Лекция 1 iconКонспект лекций по дисциплине информационные и телекоммуникационные...

Конспект лекций по курсу Системное программирвание для специальности Информатика Лекция 1 iconКонспект лекций по дисциплине “
«Компьютерная инженерия», специальности 091501 «Компьютерные сети и системы», 091502 «Системное программирование»

Конспект лекций по курсу Системное программирвание для специальности Информатика Лекция 1 iconКонспект лекций по курсу Выбранные вопросы информатики (часть 2)...
Точно так же как художник может выбирать для рисования различные инструменты, программист, создающий аплет Java, может выбирать различные...

Конспект лекций по курсу Системное программирвание для специальности Информатика Лекция 1 iconКонспект лекций по дисциплине “Статистика в машиностроении ” для студентов специальности
Конспект лекций предназначен для самостоятельного изучения студентами теоретической части курса “ Статистика в машиностроении ” (для...

Конспект лекций по курсу Системное программирвание для специальности Информатика Лекция 1 iconКонспект лекций по дисциплине “ основы защиты информации” для направления...
Министерство образования и науки украины восточноукраинский государственный университеТ

Конспект лекций по курсу Системное программирвание для специальности Информатика Лекция 1 iconКонспект лекций по курсу Начертательная геометрия
Конспект лекций по курсу начертательная геометрия (для студентов заочной формы обучения всех специальностей академии). Сост. Лусь...

Конспект лекций по курсу Системное программирвание для специальности Информатика Лекция 1 iconКонспект лекций и методические указания к выполнению контрольной работы к изучению курса
Конспект лекций и методические указания к выполнению контрольной работы по курсу “Проектирование специальных станочных и контрольных...

Конспект лекций по курсу Системное программирвание для специальности Информатика Лекция 1 iconКонспект лекций по курсу «Организация производства»
Конспект лекций по курсу «Организация производства» (для студентов и слушателей заочной формы обучения фпоизо специальностей 050100...

Вы можете разместить ссылку на наш сайт:
Школьные материалы


При копировании материала укажите ссылку © 2013
контакты
uchebilka.ru
Главная страница


<