Главная · Поиск книг · Поступления книг · Top 40 · Форумы · Ссылки · Читатели

Настройка текста
Перенос строк


    Прохождения игр    
Explanations of the situation why there is no video
StarCraft II: Wings of Liberty |#14| The Moebius Factor
StarCraft II: Wings of Liberty |#13| Breakout
StarCraft II: Wings of Liberty |#12| In Utter Darkness

Другие игры...


liveinternet.ru: показано число просмотров за 24 часа, посетителей за 24 часа и за сегодня
Rambler's Top100
Образование - Различные авторы Весь текст 2311.07 Kb

Программирование и кодирование

Предыдущая страница Следующая страница
1 ... 13 14 15 16 17 18 19  20 21 22 23 24 25 26 ... 198
         бенности написания,  наглядность (удобство чтения),  надежность и
         удобство  сопровождения прикладных программ.  Короче говоря,  эти
         методы вместе и отдельно могут быть использованы для структуриро-
         вания прикладных программ с целью повышения их качества.

                       Принципы модульного программирования

             При анализе программ,  написанных на языке Ассемблер,  обычно
         трудно  сразу  установить их структуру.  Несмотря на самые лучшие
         намерения большинства программистов,  их  программы  могут  иметь
         настолько запутанные связи и громоздкие скопления кодов, что час-
         то для их полного понимания требуется почти божественная проница-
         тельность.  Это  утверждение  ни в коем случае не рассматривается
         как неуважение к специалистам в области  программирования.  Труд-
         ности  установления  структуры являются результатом необходимости
         одновременно иметь дело с большим  количеством  деталей.  Имеются
         два направления в решении этой проблемы.  Первое направление сос-
         тоит в упрощении используемого программного кода,  замене сложной
         инструкции  последовательностью  с  более  понятными структурами.
         Технические приемы,  разработанные в главе 1,  следуя по  данному
         пути,  уменьшают количество деталей, возникающих при программиро-
         вании на языке Ассемблер.  Однако,  программисту все  еще  трудно
         справляться с большим количеством функциональных деталей.
             Второе направление состоит в применении  технических приемов,
         порожденных языками высокого уровня десятилетия тому назад.  Кон-
         цепции декомпозиции и модульного проектирования оказались  приме-
         нимыми  и  к программированию на языке Ассемблер.  Эти концепции,
         упоминаемые под общим  заголовком  "структурное  проектирование",
         позволяют  программисту  сегментировать  общую программную задачу
         таким образом,  чтобы одновременно обходиться только охватываемым
         контролем количеством деталей. Это и будет темой нашего последую-
         щего обсуждения.


                                      - 2-2 -
                               Опции проектирования

             Модульное проектирование и декомпозиция относятся  к процессу
         расчленения  больших  проблем  на более узкие,  более управляемые
         подпроблемы.  Первым шагом проектирования является решение, в ка-
         ком месте должна быть граница между этими подпроблемами.
             Для получения максимальных преимуществ от  использования  мо-
         дульного  программирования   каждая подпроблема или модуль должны
         иметь один вход и один выход.  В этом случае можно легко отслежи-
         вать  поток  управления в программе.  В любом месте модуля должна
         иметься возможнось увидеть точку входа в  модуль  и  сказать:  "Я
         знаю значения регистров X,Y и Z в этой точке, потому что они ука-
         зываются как...",  и затем проследить функционирование модуля без
         тревоги  об  искажении программы.  Один вход обеспечивает возврат
         потока управления в точку вызова при вызове модуля.  По этой при-
         чине,  модульные программы почти всегда выполняются как структуры
         CALL-RET.
             Использование нескольких  предложений  RET в модуле не должно
         нарушать правило одного входа, поскольку все инструкции RET возв-
         ращают  управление в одну и ту же точку.  Точно также,  переход к
         общему RET в конце модуля, не изменяет структуру модуля, а добав-
         ляет  лишь  коды  в модуль и увеличивает его сложность.  С другой
         стороны,  вход или выход из модуля не по этому правилу перечерки-
         вает  наибольшие  преимущества  модульного программирования:  яс-
         ность, удобство сопровождения.
             Имеется исключение из правила входа в модуль.  Это происходит
         при использовании таблицы переходов для реализации потока  управ-
         ления внутри программы. Таблица перехода используется путем "про-
         талкивания" адреса возврата в стек, вычисления индекса требуемого
         адреса  перехода в таблице и выполнения перехода в памяти. Пример
         этого приема показан в листинге  программы  драйвера  устройства,
         приведенной в главе 6.
             При практическом выполнении декомпозиции модулей можно  самим
         найти  некоторое  количество  альтернативных решений.  Прежде чем
         осуществить правильный выбор, необходимо знать альтернативы. Цель
         состоит  в  выборе таких альтернатив,  которые создадут наилучшие
         условия проектирования.

                            Функциональная декомпозиция

             При обращении к проблеме на стадии проектирования первым аль-
         тернативным выбором должна быть функциональная декомпозиция, т.е.
         разбиение проблемы на более узкие,  вполне поддающиеся управлению
         функциональные единицы, где каждая единица выполняет завершенную,
         легко идентифицируемую задачу.  Имеется множество путей определе-
         ния  содержания задачи.  Вот лишь некоторые примеры подобных еди-
         ниц, которые выполняют определенные функции: получение квадратно-
         го корня некоторого числа;  выполнение всех операций относительно
         указанного устройства таких, как операции в/в диска, операции в/в
         клавиатуры;  выполняющие  общую группу действий в указанное время
         такие, как инициализация областей данных; и единицы, которые вза-
         имодействуют последовательно или используют общие элементы данных
         такие,  как считывание данных с клавиатуры и преобразование их  в
         целые значения.
             В настоящее время в области программирования на языках  высо-
         кого уровня чаще всего принимаются такие решения,  которые предс-
         тавляют собой наилучший способ по использованию сегментации прог-

                                      - 2-3 -
         рамм. При  программировании на языке Ассемблер обычно нельзя быть
         столь последовательным. Каждый из ранее приведенных способов под-
         водит, по крайней мере, к начальной точке для разбиения проблемы.
         Часто обнаруживается,  что некоторые модули связываются с помощью
         одного набора критериев, а другие модули - с помощью другого. По-
         ка каждый модуль включает  легко  понимаемые  программные  секции
         (обычно две страницы или меньше), Вы находитесь на правильном пу-
         ти.

                  Минимизации количества передаваемых параметров

             Иногда обнаруживается, что после определения модулей програм-
         мы   создано  нечто  громоздкое и неуклюжее.  Это часто случается
         тогда,  когда модули при выполнении возложенных на них задач тре-
         буют доступа к обширному количеству данных.  Чаще всего это легко
         может произойти,  если на модуль возложено выполнение  нескольких
         опций.  Чтобы  знать  состояние программы в данное время,  модуль
         должен принимать очень много различных переменных.  Если это так,
         и  выявлено,  что модуль принимает большое количество параметров,
         необходимо ответить на следующие две группы вопросов:
             Первая: В этом модуле предпринята попытка выполнения несколь-
         ких функций? Требует ли модуль параметры, используемые в не отно-
         сящихся к данному модулю секциях?  Если ответы на эти вопросы по-
         ложительные,  то  необходимо  снова   обратиться   к   дальнейшей
         сегментации этого модуля.
             Вторая: Модуль представляет собой функциональный разрез?  Яв-
         ляются ли на самом деле вызывающий и вызываемый модули частью од-
         ной и той же функции? Если это так, то поместите их вместе в один
         модуль, даже если результирующий модуль окажется слишком большим.
         Затем попробуйте выполнить сегментацию  модуля  снова  различными
         способами.
             Сегментация модулей через функциональный разрез часто  проис-
         ходит тогда,  когда программист обнаруживает, что две программные
         секции идентичны или сильно похожи друг на друга. Программист за-
         тем  пытается создать из них один модуль.  Это не модульное прог-
         раммирование,  поскольку результирующий модуль имеет не  функцио-
         нальное соединение.
             Если в процессе проектирования будет обнаружено,  что  ничего
         сделать нельзя,  чтобы избежать использования большого числа ссы-
         лок на данные или передачи меток параметров,  вернитесь обратно в
         начало проектирования и проверьте корректность поставленной проб-
         лемы.

                    Минимизации количества необходимых вызовов

             Одним из существенных преимуществ модульного программирования
         является  то,  что  программа  основного уровня очень часто может
         быть сконструирована для чтения как последовательность вызываемых
         процедур.  Этот факт существенно повышает "понимаемость" програм-
         мы,  поскольку читатель может познакомиться с ее основным потоком
         и  функционированием  после  прочтения  только одной-двух страниц
         программного кода.  Однако   эта особенность может также иметь  и
         недостатки. Одна из многих верхних статистических оценок програм-
         мирования говорит о том, что 90% времени выполнения типовых прог-
         рамм расходуется в 10 % кода программы. При этом подразумевается,
         что если эти 10 %  содержат большое количество цепочечных вызовов
         процедур, то суммарное время, затрачиваемое на управление  выпол-

                                      - 2-4 -
         нением программы,  может стать непреодолимым препятствием на пути
         использования этого подхода.
             Прежде чем отказаться от модульности проектируемой программы,
         проверьте,  что скрывается под зависимостью программы от времени.
         Во-первых, большинство программ затрачивают большую часть времени
         выполнения на ожидание ввода информации с клавиатуры. После нажа-
         тия клавиши требуемые функции, с точки зрения выполнения длитель-
         ного процесса, обычно не расходуют время. Различие между 100 мик-
         росекунд и 100 миллисекунд для среднего пользователя неразличимо.
             Противоположным для некоторых мнением является то,  что дейс-
         твующий механизм пары CALL - RET не перекрывает потребляемое вре-
         мя. По сравнению с инструкциями перехода инструкция CALL выполня-
         ется на 30-50% дольше, а RET в среднем длиннее на 1 цикл.  Только
         когда во внимание принимаются накладные расходы передачи парамет-
         ров,  сохранения регистров и т.д., называемые служебными расхода-
         ми,   модульные  программы  начинают выглядеть медленнее по срав-
         нению с немодульными программами. В дополнение к тому, что модули
         модульных программ обычно являются более общими,  чем их неструк-
         турированные дубликаты, модули модульных программ могут использо-
         вать ссылки на память или стек с большей частотой. Дополнительное
         время,  расходуемое на вычисление действительного адреса  в  теле
         модуля,  может привести к замедлению выполнения конкретного моду-
         ля, чем узко закодированная конкретная программа.
             Преимущества служебных программ  и программ общего назначения
         заключаются в том, что модуль может быть использован виртуально в
         некотором  месте  программы.  При написании немодульной программы
         программист может потратить несколько часов, пытаясь открыть: ис-
         пользуется ли регистр,  или хуже того, верно ли то, что он должен
Предыдущая страница Следующая страница
1 ... 13 14 15 16 17 18 19  20 21 22 23 24 25 26 ... 198
Ваша оценка:
Комментарий:
  Подпись:
(Чтобы комментарии всегда подписывались Вашим именем, можете зарегистрироваться в Клубе читателей)
  Сайт:
 

Реклама