Мы поможем в написании ваших работ!



ЗНАЕТЕ ЛИ ВЫ?

Методическое пособие по выполнению лабораторных работ по курсу «системное программное обеспечение и операционные системы»

Поиск

Методическое пособие по выполнению лабораторных работ по курсу «Системное программное обеспечение и операционные системы»

 

г. Харьков, 2005 г.

 


 

Предисловие

Предлагаемое издание предназначено для изучения основ программирования в инструментальной среде Visual C++ и получения практических навыков проектирования системных Win32- разрядных приложений в операционных системах Windows98/NT/XP. Его материал ориентирован на студентов, профессионально изучающих программирование на персональных ЭВМ.

Методическое пособие содержит перечень лабораторных работ по курсу «Системное программное обеспечение». В начале каждой лабораторной работы дан краткий теоретический материал, а в конце - перечень контрольных вопросов для самоконтроля студентов.

Выполняя лабораторные работы № 1-10, студенты изучают разработку Win 32 -разрядных приложений в операционных системах Windows98/NT|XP. В качестве инструментальных средств разработки студенты должны использовать Visual C++, Delphi, Borland C++, Builder C++.

По окончании курса студент должен уметь разрабатывать системные Win32 -разрядные приложения в операционных системах Windows/98/NT|XP.

В данное пособие включены лабораторные работы, позволяющие получить практические навыки написания Win32-разрядных системных приложений, использующих механизмы доступа к логическим томам и файлам, многозадачности, распределения памяти, работы с системным РЕЕСТРОМ, обмена данными. В качестве инструментальных средств разработки Windows-приложений студенты могут использовать следующие: Visual C++, Delphi, Borland C++, Builder C++.

Существуют различные типы Win32 -разрядных приложений: традиционные Windows-приложения, использующие интерфейс графических устройств (GDI) и обрабатывающие системные сообщения Windows; консольные Win32 -разрядные приложения, в окне которых отображается только текстовая информация, в этих приложениях отсутствуют окна сообщений, контексты устройств и т.д.; динамически подключаемые библиотеки DLL, которые строго говоря не являются законченным Windows- приложением, не отображают информацию на экране и не обрабатывают сообщения Windows. Программа либо явно загружает библиотеку, либо вызывает одну из функций этой библиотеки.

В системе Windows определены сотни сообщений, функции обработки которых входят в состав Win32 API (интерфейс прикладных программ). Win32 API реализован на четырех платформах: Win32S, Windows NT, Windows 95, WindowsCE. Приложение взаимодействует с Windows через интерфейс API. В описании лабораторных работ содержатся примеры использования Win32 API.

Лабораторная работа № 1.

Интегрированный отладчик Microsoft Visual C++ 6.0

Цель работы. Изучить и освоить возможности и основные приемы работы с отладчиком.

Теоретические сведения

Начинающим программистам отчасти трудно в полной мере оценить важность усвоения хороших «программных привычек», которые способствуют проектированию удобочитаемых и надежных алгоритмов. Студенческие программы, реализованные по таким алгоритмам, обычно невелики (редко более двух – трех сотен строк кода). С другой стороны, приложения реального мира могут быть очень велики (несколько тысяч или десятков тысяч строчек кода). Разрабатываются такие программы группами программистов, и используют эти программы обычно в течение долгого периода времени, поэтому требуют сопровождения, если они должны отвечать меняющимся условиям, сохраняя при этом корректность; часто программу сопровождает не написавший ее программист, а кто-то другой.

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

Обнаружение и исправление ошибок является важной частью разработки программного обеспечения и называется проверкой действительности и корректности. Под проверкой действительности понимается проверка того, что алгоритмы и программа в целом отвечают спецификациям задачи. Проверка корректности (верификация) относится к правильности и полноте алгоритмов и всей программы. Действительность можно охарактеризовать вопросом: «Решает ли программа правильную задачу?». Корректность, со своей стороны, соответствует вопросу: «Решает ли программа задачу правильно?»

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

· Синтаксические или времени компиляции. Ошибки, возникающие во время компиляции.

· Компоновщика. Ошибки, возникающие на этапе компоновки, которая производится для получения исполняемого файла.

· Времени выполнения. Ошибки, возникающие при выполнении программы.

· Логические. Приложение по видимости выполняется без ошибок, однако выдает неверные результаты.

Синтаксические ошибки. Эти ошибки являются самым частым типом ошибок. Они возникают, когда в программе встречается оператор, нарушающий какое-либо из грамматических или синтаксических правил выбранного языка программирования. Эти ошибки автоматически детектируются при компиляции программы.

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

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

Компилятор Visual C++ может сообщать об объявлениях переменных, которые никогда не используются, и о чтении значения переменной до ее инициализации. Он может даже определить, что логический поток управления вашей программы не допускает исполнения некоторых сегментов кода, - в этом случае компилятор сообщает о «недостижимом коде».

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

Например, функция socket объявляется в файле <WinSock2.h>, и для правильной компиляции программы требует препроцессорной директивы #include <WinSock2.h>. Однако такая программа все равно не будет компоноваться без ошибок, потому что компоновщик не подключает сетевую библиотеку автоматически. Нужно явным образом дать ему такое указание (рис. 1.1.), либо добавив файл библиотеки Ws2_32.lib в проект, либо указав в настройках проекта (Project->Settings, вкладка Link):

Рис 1.1. Добавление библиотеки в проект

На этом рисунке в окне ввода Object/Library modules виден список используемых приложением библиотек, и Ws2_32.lib, добавленная нами.

Ошибки времени выполнения. После того, как будут устранены.все ошибки времени компиляции, и компоновщик создаст исполняемый файл, программу можно запускать на выполнение. Но ошибки могут случаться во время работы программы и способствовать аварийному (преждевременному) ее завершению, потому что происходит некоторое событие, с которым компьютер не может справиться.

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

Ошибки времени выполнения включают в себя следующее.

· Аппаратно детектируемые ошибки, такие как деление на ноль, арифметическое переполнение, нарушение защиты памяти и ошибки устройств.

· Системные ошибки, например, неудачная файловая операция или переполнение очереди сообщений.

· Логические ошибки, например, выход индекса за границы массива или удаление элемента из пустой очереди.

· Исключения или ошибки, специфичные для приложения, такие как неверный формат ввода.

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

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

Отыскивать такие ошибки проще всего с помощью символического отладчика. Отладчик Microsoft Visual C++ позволяет вам проследить выполнение программы, исполняя ее по одному оператору (пошагово), пока не встретится оператор, генерирующий ошибку. Как только ошибка идентифицирована, ее нужно исправить, заменив некорректный оператор корректным, а затем заново компилировать, компоновать и запустить программу на выполнение.

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

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

Другим подходом к поиску логических ошибок является вставка операторов вывода в ключевых точках программы, чтобы отображать значения переменных, участвующих в вычислении неверных результатов (printf -отладка). Прослеживая вручную выполнение кода и сравнивая выведенные значения с ожидаемыми, можно по их расхождению локализовать ошибку.

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

Расшифровка сообщений об ошибках. Когда вы компилируете и компонуете программу в Visual C++, автоматически открывается окно Output, отображающее информацию о статусе процесса построения, включая все предупреждения и сообщения об ошибках. Это окно может помочь вам найти и исправить причины сообщения об ошибке двумя способами:

· автоматически проследив строку кода, генерировавшую сообщение,

· отобразив страницу контекстно-зависимой справки, содержащей дополнительную информацию о данном сообщении.

Чтобы увидеть оператор, генерировавший некоторое сообщение, нужно просто дважды щелкнуть на этом сообщении в окне Output (либо нажать клавишу F4). Откроется нужный файл, и указатель выделит строчку, которая вызвала ошибку.

Чтобы получить справку о данном сообщении, нужно сначала щелкнуть на номере сообщения в окне Output (например, С2001) а затем нажать клавишу F1. В окне Help откроется страница справочника, соответствующая выбранному номеру ошибки.

Часто в этих справочных файлах приводится объяснение ошибки в синтаксисе или логике, которое помогает исправить ошибочный оператор.

 

1.2. Работа с отладчиком Microsoft Visual C++

Среда разработки Visual C++ прелагает программисту различные инструменты, позволяющие быстро и эффективно находить ошибки в исходном коде и компонентах программы.

Визуальный интерфейс отладчика включает в себя специальные меню, окна, панели диалогов. Вы можете даже пользоваться «перетаскиванием» Windows для обмена информацией между компонентами отладчика. Конфигурация отладчика должна быть установлена до того, как начнется процесс отладки.

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

Подключение отладчика

Перед тем, как запустить отладчик Visual C++, нужно построить отладочную версию вашей программы. Для такой версии компилятор вставляет в объектные файлы дополнительную символическую информацию. Отладочное построение в C++ устанавливается по умолчанию, но если вы перед этим выполняете построение тиражируемой версии, то следует снова выбрать отладочную.

Перед выбором типа целевого файла необходимо убедиться, что выбран нужный активный проект (требуется только в случае, когда открыто более одного проекта). Для этого в меню Project выберите пункт Set Active Project. Если проектов в списке несколько, выберите тот, который хотите построить.

На рис 1.2 показана инструментальная панель Build с двумя целевыми типами в выпадающем списке. Выберите пункт Win32 Debug. В панели (слева направо) расположены:

· выпадающий список выбора активного проекта (выбран Project1),

· выпадающий список целевого типа (Win32 Debug),

· кнопки Compile (компилировать текущий файл), Build (построить весь проект), Stop (отменить построение или компиляцию), Execute (запустить программу без отладки), Go (запустить программу в отладчике) и Insert / Remove Breakpoint (добавить / удалить точку останова в текущей строке).

 

Рис. 1.2. Выбор целевой версии Win32 Debug

В предположении, что программа уже успешно скомпилирована, для запуска ее в отладчике нужно выбрать один из пунктов меню Build (рис. 1.3.). Некоторые пункты этого меню продублированы в панели Build..

 

Рис. 1.3. Запуск отладчика из меню Build.

 

Ниже приведены описания команд меню Build:

· Go. Эта команда запускает отладчик и/или исполняет программу (с полной скоростью), пока не встретится точка останова или конец программы, либо она будет остановлена для пользовательского ввода. Эта команда аналогична кнопке Go инструментальной панели;

· Step Into. Эта команда запускает отладчик и/или исполняет программу в пошаговом режиме. Когда текущим оператором является вызов функции или метода, отладчик входит внутрь соответствующей процедуры;

· Run To Cursor. Эта команда запускает отладчик и/или исполняет программу до строки, в которой установлен текстовый курсор. Команду можно применять в качестве альтернативы установке обычной точки останова.

· Attach To Process… Прикрепляет отладчик к уже работающему процессу. После этого можно приостановить процесс и отлаживать его как обычно.

 

При компиляции программы с предупреждающими сообщениями ее можно запускать. Нельзя запускать программу только с сообщениями об ошибках.

После запуска отладчика на экране появится новая панель инструментов Debug (рис. 1.4)

 

Рис. 1.4. Панель инструментов отладки

 

В панели расположены следующие кнопки: (слева направо):

· Restart. Эта команда указывает отладчику, что вы хотите запустить программу с самого начала, а не с текущей позиции отладки.

· Stop Debugging. Если в какой-то момент фазы отладки вы осознаете, что проект или рабочее пространство необходимо обновить, то для возврата в режим разработки необходимо нажать эту кнопку, которая завершает отладчик.

· Break Execution. Эта команда останавливает исполнение программы в текущей точке.

· Apply Code Changes, Edit And Continue. С помощью этой команды вы можете внести в программу изменения исходного кода, произведенные в процессе отладки. Эта команда применяется при работе или приостановке программы в отладчике. Для внесения в отлаживаемую программу сделанных изменений выберите Apply Code Changes.

· Edit And Continue. В случае включенной этой опции можно вносить изменения автоматически по командам Go и Step.

· Show Next Statement. Эта команда показывает следующий оператор программного кода. Если исходный код не доступен, эта команда показывает оператор в окне дизассемблера.

· Step Into. При выполнении этой команды для оператора с вызовом процедуры (функции или метода) производится переход внутрь вызванной процедуры.

· Step Over. При включении этой опции для оператора с вызовом процедуры отладчик перешагивает через вызванный код, который выполняется с максимальной скоростью. Программа останавливается на первом операторе после вызова.

· Step Out. Эта команда заставляет отладчик переключиться на полную скорость исполнения до конца текущей функции и остановиться на инструкции непосредственно после возврата из нее. Команду можно применить для быстрого возврата из отлаживаемой функции, когда вы убедились, что ошибка находится не в ней.

· Run To Cursor. Эта команда похожа на Go, но ей не требуется предварительно определенной точки останова. Для выполнения Run To Cursor нужно просто установить курсор редактора в строку исходного кода, с которой вы хотите продолжить отладку, и выбрать соответствующий значок.

· Quick Watch. Команда открывает окно Quick Watch, в котором вы можете оценивать значения выражений.

· Watch. Эта команда открывает окно Watch, в котором отображаются переменные приложения по их именам, а так же выбранные выражения.

· Variables. Значок открывает окно Variables, в котором отображается информация о переменных текущего и предыдущего операторов, а также возвращаемые функциями значения (страница Auto), локальные переменные текущей функции (страница Locals) и объект, некоторый указывает this (страница this).\

· Registers. Команда открывает окно Registers отладчика, отображающее регистры общего назначения CPU и состояние его флагов.

· Memory. Команду можно использовать для открытия окна Memory, отображающего состояние памяти программы.

· Call Stack. Открывает окно стека вызовов, где отладчик перечисляет вызванные к данному моменту функции, которые еще не закончились.

· Disassembly. Открывает окно, в котором показан код языка ассемблера, полученный в результате дизассемблирования компилированной программы.

 

Форматирующие символы дисплея отладчика. Табл. 1.1.

Символ Формат Значение Представление
d, I Десятичное целое со знаком 0xF000F061 -268373911
U Десятичное целое без знака 0x0066  
O Восьмеричное целое без знака 0xF064  
x, X Шестнадцатеричное целое 70148 (десятичное) 0x000011204
l, h Префикс long или short для d, I,U, O, x, X 00406040,hx 0x0c20
F Десятичная нотация со знаком 5./2. 2.500000
E Научная нотация со знаком 5./2. 2.500000+004
G Десятичная или научная нотация со знаком, какая короче 5./2. 2.5
С Одиночный символ 0x0066 ‘f’
S Строка 0x012fde8 “The String”
su Строка Unicode   “The String”
St Строка Unicode или ANSI в зависимости от установки Unicode Strings    
Hr HRESULT код ошибки Win32 0x00000000L S_OK
wc Флаг класса Windows 0x00000040 WC_DEFAULT
wm Номер сообщения Windows 0x000 WM_CLOSE

 

Вы можете так же пользоваться форматирующими значениями для содержимого памяти в применении к любым выражениям, оцениваемым как адрес. Для представления массива символов в виде строки поставьте перед именем массива символ &, например, &ArrayName. Можно за выражением поставить форматирующий символ, например &ArrayName,x.

 

Варианты заданий

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

· Цикл.

· Вызов функций (минимум два уровня вложенности).

· Работа с char* строками.

Используя построенное приложение, вам необходимо научиться использовать контрольные точки, обработку вызовов функций, просмотр и интерпретацию переменных как различных типов данных.

 

1.6. Контрольные вопросы

1. Какие существую проблемы в связи с ошибками?

2. Типы бывают типы ошибок, когда возникают?

3. Как к проекту подключаются дополнительные модули?

4. Как выполняется расшифровка сообщений об ошибках отладчика?

5. Как выполняется запуск отладчика.

6. Для чего предназначено меню Build и содержащиеся в нем команды? Привести краткое описание команд.

7. Для чего предназначена панель Debug и содержащиеся в ней команды? Привести краткое описание команд.

8. Какая информация отображается в окне Variables?

9. Какая информация отображается в окне Watch?

10. Какая информация отображается в окне Registers?

11. Какая информация отображается в окне Memory?

12. Какая информация отображается в окне Call Stack?

13. Какая информация отображается в окне Disassembly?

14. Как осуществляется форматирование представления переменных в окне Watch?

 

Лабораторная работа № 2

Теоретические сведения

Основные команды ассемблера. Ниже описаны все непривилегированные команды процессоров Intel серии х86, включая команды расширений IA NPX (чаще называемый FPU — расширение для работы с числами с плавающей запятой) и IA MMX (мультимедийное расширение). Для каждой команды указана форма записи, название и модель процессоров Intel, начиная с которой она поддерживается: 8086, 80186, 80286, 80386, 80486, Р5 (Pentium), MMX, P6 (Pentium Pro и Pentium II).

Пересылка данных. Табл. 2..1.

· Команда: MOV приемник, источник
· Назначение: Пересылка данных
· Процессор:  

Базовая команда пересылки данных. Копирует содержимое источника в приемник, источник не изменяется. Команда MOV действует аналогично операторам присваивания из языков высокого уровня, то есть команда

mov ax,bx

эквивалентна выражению

ах:= bх; языка Паскаль или ах = bх; языка С, за исключением того, что команда ассемблера позволяет работать не только с переменными в памяти, но и со всеми регистрами процессора.

В качестве источника для MOV могут использоваться: число (непосредственный операнд), регистр общего назначения, сегментный регистр или переменная (то есть операнд, находящийся в памяти). В качестве приемника — регистр общего назначения, сегментный регистр (кроме CS) или переменная. Оба операнда должны быть одного и того же размера — байт, слово или двойное слово.

Нельзя выполнять пересылку данных с помощью MOV из одной переменной в другую, из одного сегментного регистра в другой.

Нельзя помещать в сегментный регистр непосредственный операнд , эти операции выполняют двумя командами (из сегментного регистра в обычный и уже из него в другой сегментный) или парой команд PUSH/POP.

Загрузка регистра SS командой MOV автоматически запрещает прерывания до окончания следующей за этим команды MOV, так что можно загрузить SS и ESP двумя последовательными командами MOV, не опасаясь, что в этот момент произойдет прерывание, обработчик которого получит неправильный стек. В любом случае для загрузки значения в регистр SS предпочтительнее команда

Пересылка данных. Табл. 2.2

· Команда: CMOVcc приемник, источник
· Назначение: Условная пересылка данных
· Процессор: P6

Это набор команд, которые копируют содержимое источника в приемник, если удовлетворяется, то или иное условие (см. табл.2.3). Источником может быть регистр общего назначения или переменная, а приемником только регистр. Условие, которое должно удовлетворяться,— просто равенство нулю или единице тех или иных флагов из регистра FLAGS, но, если использовать команды CMOVc c сразу после команды СМР (сравнение) с теми же операндами, условия приобретают особый смысл, например:

cmp ах,bх; сравнить ах и bх cmovl ax,bx; если ах < bх, скопировать bх в ах

Слова «выше» и «ниже» в таблице 2.3. относятся к сравнению чисел без знака, слова «больше» и «меньше» учитывают знак.

Разновидности команды CMOVcc. Табл.2.3

Код команды Реальное условие Условие для CMP
CMOVA CMOVNBE CF = 0 и ZF = 0 если выше если не ниже или равно
CMOVAE CMOVNB CMOVNC CF = 0 если выше или равно если не ниже если нет переноса
CMOVB CMOVNAE CMOVC CF = 1 если ниже если не выше или равно если перенос
CMOVBE CMOVNA CF = 1 и ZF = 1 если ниже или равно если не выше
CMOVE CMOVZ ZF = 1 если равно если ноль
CMOVG CMOVNLE ZF = 0 и SF = OF если больше если не меньше или равно
CMOVGE CMOVNL SF = OF если больше или равно если не меньше
CMOVL CMOVNGE SF <> OF если меньше если не больше или равно
CMOVLE CMOVNG ZF = 1 и SF <> OF если меньше или равно если не больше
CMOVNE CMOVNZ ZF = 0 если не равно если не ноль
CMOVNO OF = 0 если нет переполнения
CMOVO OF = 1 если есть переполнение
CMOVNP CMOVPO PF = 0 если нет четности если нечетное
CMOVP CMOVPE PF = 1 если есть четность если четное
CMOVNS SF = 0 если нет знака
CMOVS SF = 1 если есть знак

Табл.2.4.

· Команда: XCHG операнд1, операнд2
· Назначение: Обмен операндов между собой
· Процессор:  

Содержимое операнда 2 копируется в операнд 1, а старое содержимое операнда 1 — в операнд 2. XCHG можно выполнять над двумя регистрами или над регистром и переменной.

xchg eax,ebx; то же, что три команды на языке С:temp = eax; eax = ebx; ebx = temp; xchg al,al; а эта команда не делает ничего Табл.2.5
· Команда: BSWAP регистр32
· Назначение: Обмен байт внутри регистра
· Процессор:  

Обращает порядок байт в 32-битном регистре. Биты 0—7 (младший байт младшего слова) меняются местами с битами 24—31 (старший байт старшего слова), а биты 8—15 (старший байт младшего слова) меняются местами с битами 16—23 (младший байт старшего слова).

mov eax,12345678h bswap eax; теперь в еах находится 78563412h

Чтобы обратить порядок байт в 16-битном регистре, следует использовать команду XCHG:

xchg al,ah; обратить порядок байт в АХ

В процессорах Intel команду BSWAP можно использовать и для обращения порядка байт в 16-битных регистрах, но в некоторых совместимых процессорах других фирм этот вариант BSWAP не реализован.

Табл.2.6.
· Команда: PUSH источник
· Назначение: Поместить данные в стек
· Процессор:  

Помещает содержимое источника в стек. Источником может быть регистр, сегментный регистр, непосредственный операнд или переменная. Фактически эта команда копирует содержимое источника в память по адресу SS:[ESP] и уменьшает ESP на размер источника в байтах (2 или 4). Команда PUSH практически всегда используется в паре с POP (считать данные из стека). Так, например, чтобы скопировать содержимое одного сегментного регистра в другой (что нельзя выполнить одной командой MOV), можно использовать такую последовательность команд:

push cspop ds; теперь DS указывает на тот же сегмент, что и CS

Другое частое применение команд PUSH/POP — временное хранение переменных, например:

push eax; сохраняет текущее значение ЕАХ...; здесь располагаются какие-нибудь команды,; которые используют ЕАХ, например CMPXCHG pop eax; восстанавливает старое значение ЕАХ

Начиная с 80286, команда PUSH ESP (или SP) помещает в стек значение ESP до того, как эта же команда его уменьшит, в то время как на 8086 SP помещался в стек уже уменьшенным на два.

Табл.2.7
 Команда: POP приемник
 Назначение: Считать данные из стека
 Процессор:  

Помещает в приемник слово или двойное слово, находящееся в вершине стека, увеличивая ESP на 2 или 4 соответственно. POP выполняет действие, полностью обратное PUSH. Приемником может быть регистр общего назначения, сегментный регистр, кроме CS (чтобы загрузить CS из стека, надо воспользоваться командой RET), или переменная. Если в роли приемника выступает операнд, использующий ESP для косвенной адресации, команда POP вычисляет адрес операнда уже после того, как она увеличивает ESP.

Табл.2.8
· Команда: PUSHA PUSHAD
· Назначение: Поместить в стек все регистры общего назначения
· Процессор: 80186 80386

PUSHA помещает в стек регистры в следующем порядке: АХ, СХ, DX, ВХ, SP, ВР, SI и DI. PUSHAD помещает в стек ЕАХ, ЕСХ, EDX, ЕВХ, ESP, EBP, ESI и EDI. (В случае SP и ESP используется значение, которое находилось в этом регистре до начала работы команды.) В паре с командами POPA/POPAD, считывающими эти же регистры из стека в обратном порядке, это позволяет писать подпрограммы (обычно обработчики прерываний), которые не должны изменять значения регистров по окончании своей работы. В начале такой подпрограммы вызывают команду PUSHA, а в конце— РОРА.

На самом деле PUSHA и PUSHAD — одна и та же команда с кодом 60h. Ее поведение определяется тем, выполняется ли она в 16- или в 32-битном режиме. Если программист использует команду PUSHAD в 16-битном сегменте или PUSHA в 32-битном, ассемблер просто записывает перед ней префикс изменения размерности операнда (66h).

Это же будет распространяться на некоторые другие пары команд: РОРА/POPAD, POPF/POPFD, PUSHF/PUSHFD, JCXZ/JECXZ, CMPSW/CMPSD, INSW/INSD, LODSW/LODSD, MOVSW/MOVSD, OUTSW/OUTSD, SCASW/SCASD и STOSW/STOSD.

Табл.2.9
· Команда: POPA POPAD
· Назначение: Загрузить из стека все регистры общего назначения
· Процессор: 80186 80386

Эти команды выполняют действия, полностью обратные действиям PUSHA и PUSHAD, за исключением того, что помещенное в стек значение SP или ESP игнорируется. РОРА загружает из стека DI, SI, BP, увеличивает SP на два, загружает ВХ, DX, CX, AX, a POPAD загружает EDI, ESI, ЕВР, увеличивает ESP на 4 и загружает ЕВХ, EDX, ЕСХ, ЕАХ.

Табл.2.10.
· Команда: IN приемник, источник
· Назначение: Считать данные из порта
· Процессор:  

Копирует число из порта ввода-вывода, номер которого указан в источнике, в приемник. Приемником может быть только AL, АХ или ЕАХ. Источник— или непосредственный операнд, или DX, причем можно указывать только номера портов не больше 255.

Табл.2.11.
· Команда: OUT приемник, источник
· Назначение: Записать данные в порт
· Процессор:  

Копирует число из источника (AL, АХ или ЕАХ) в порт ввода-вывода, номер которого указан в приемнике. Приемник может быть либо непосредственным номером порта, либо регистром DX. На командах IN и OUT строится все общение процессора с устройствами ввода-вывода — клавиатурой, жесткими дисками, различными контроллерами, и используются они, в первую очередь, в драйверах устройств. Например, чтобы включить динамик ПК, достаточно выполнить команды:

in al,61h or al,3 out 61h,al Табл.2.12.
· Команда: CWD
· Назначение: Конвертирование слова в двойное слово
· Процессор:  
Табл.2.13.
· Команда: CDQ
· Назначение: Конвертирование двойного слова в учетверенное
· Процессор:  

Команда CWD превращает слово в в двойное слово, младшая половина которого (биты 0—15) остается в АХ, а старшая (биты 16—31) располагается в DX. Команда CDQ выполняет аналогичное действие по отношению к двойному слову в ЕАХ, расширяя его до учетверенного слова в EDX:EAX. Эти команды всего лишь устанавливают все биты регистра DX или EDX в значение, равное значению старшего бита регистра АХ или ЕАХ, сохраняя таким образом его знак.

Табл.2.14.
 Команда: CBW
 Назначение: Конвертирование байта в слово
 Процессор:  
Табл.2.15.
 Команда: CWDE
 Назначение: Конвертирование слова в двойное слово
 Процессор:  

CBW расширяет байт, находящийся в регистре AL, до слова в АХ, CWDE расширяет слово в АХ до двойного слова в ЕАХ. CWDE и CWD отличаются тем, что CWDE располагает свой результат в ЕАХ, в то время как CWD, команда, выполняющая точно такое же действие, располагает результат в паре регистров DX:AX. Так же как и команды CWD/CDQ, расширение выполняется путем установки каждого бита старшей половины результата равным старшему биту исходного байта или слова, то есть:

mov al,0F5h; AL = 0F5h = 245 = -11 cbw; теперь АХ = 0FFF5h = 65 525 = -11Так же как и в случае с командами PUSHA/PUSHAD, пара команд CWD/CDQ — это одна команда с кодом 99h, и пара команд CBW/CWDE — одна команда с кодом 98h. Интерпретация этих команд зависит от того, в каком (16-битном или в 32-битном) сегменте они исполняются, и точно так же, если указать CDQ или CWDE в 16-битном сегменте, ассемблер поставит префикс изменения разрядности операнда. Табл.2.16.
 Команда: MOWSX приемник, источник
 Н


Поделиться:


Последнее изменение этой страницы: 2016-04-26; просмотров: 471; Нарушение авторского права страницы; Мы поможем в написании вашей работы!

infopedia.su Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. Обратная связь - 3.135.184.186 (0.012 с.)