ЭКЗАМЕНАЦИОННЫЙ БИЛЕТ № 4
1. Структура программы. Создание главного окна. Программа, написанная на ассемблере MASM, может состоять из нескольких частей, называемых модулями, в каждом из которых могут быть определены один или несколько сегментов данных, стека и кода. Любая законченная программа на ассемблере должна включать один главный, или основной (main), модуль, с которого начинается ее выполнение. Основной модуль может содержать программные сегменты, сегменты данных и стека, объявленные при помощи упрощенных директив. Кроме того, перед объявлением сегментов нужно указать модель памяти при помощи директивы .MODEL. Поскольку подавляющее большинство современных приложений являются 32-разрядными, то основное внимание в этом разделе мы уделим именно таким программам, хотя не обойдем вниманием и 16-разрядные программы, которые все еще используются. Начнем с 16-разрядных программ. В следующем примере показана 16-разрядная программа на ассемблере, в которой используются упрощенные директивы ассемблера MASM:
Здесь оператор end main указывает на точку входа main в главную процедуру. Оператор end закрывает последний сегмент и обозначает конец исходного текста программы. В 16-разрядных приложениях MS-DOS можно инициализировать сегментные регистры так, чтобы они указывали на требуемый логический сегмент данных. Листинг 4.1 демонстрирует это. Листинг 4.1. Пример адресации сегментов в программе MS-DOS
Здесь на экран дисплея выводится строка s1. При помощи следующих команд в сегментный регистр DS помещается адрес сегмента данных, указанного директивой .data:
Затем строка s1, адресуемая через регистры DS:DX, выводится на экран с использованием прерывания 9h функции 21h MS-DOS. Попробуйте закомментировать проанализированные две строки кода и посмотреть на результат работы программы. Для 32-разрядных приложений шаблон исходного текста выглядит иначе:
Основное отличие от предыдущего примера — другая модель памяти (flat), предполагающая 32-разрядную линейную адресацию с атрибутом near. Как видно из примера, “классический” шаблон 32-разрядного приложения содержит область данных (определяемую директивой .data), область стека (директива .stack) и область программного кода (директива .code). Может случиться так, что 32-разрядному приложению на ассемблере потребуется несколько отдельных сегментов данных и/или кода. В этом случае разработчик может создать их с помощью директивы SEGMENT. Директива SEGMENT определяет логический сегмент и может быть описана следующим образом:
Замечу, что директива SEGMENT может применяться с любой моделью памяти, не только flat. При использовании директивы SEGMENT потребуется указать компилятору на то, что все сегментные регистры устанавливаются в соответствии с моделью памяти flat. Это можно сделать при помощи директивы ASSUME:
Регистры FS и GS программами не используются, поэтому для них указывается атрибут ERROR. Сейчас мы рассмотрим программный код 32-разрядной процедуры на ассемблере (она называется _seg_ex), в которой используются два логических сегмента данных. Процедура выполняет копирование строки src, находящейся в сегменте данных data1, в область памяти dst в сегменте данных data2 и содержит один логический сегмент программного кода (code segment). Успокою читателей, незнакомых с принципами работы процедур (они рассмотрены далее в книге): в данном случае нас будет интересовать код внутри процедуры _seg_ex (команды, находящиеся между директивами _seg_ex proc и _seg_ex endp). Исходный текст программного кода процедуры _seg_ex представлен в листинге 4.2. Листинг 4.2. Использование двух логических сегментов данных в 32-разрядной процедуре
При использовании модели flat доступ к данным осуществляется по 32-разрядному смещению, поэтому смысл показанных ниже команд, загружающих адреса логических сегментов (а заодно и адреса строк src и dst) в регистры ESI и EDI, думаю, понятен:
Группа следующих команд выполняет копирование строки src в dst, при этом регистр CX содержит количество копируемых байтов:
В регистре EAX возвращается адрес строки-приемника dst. Обращаю внимание читателей на то, что никакой инициализации сегментных регистров не требуется, поскольку это делается при помощи директивы .model flat. Еще один важный момент: программа, использующая модель flat, выполняется в одном физическом сегменте, хотя логических сегментов может быть несколько, как в нашем случае. Работоспособность процедуры легко проверить, вызвав ее из программы на Visual C++ .NET (нужно только включить объектный файл процедуры в проект приложения). Исходный текст приложения приведен в листинге 4.3. Листинг 4.3. Программа, вызывающая процедуру seg_ex
Здесь процедура seg_ex является внешней, поэтому объявлена как extern. Результатом выполнения программы будет строка на экране дисплея
Первое окно, которое создает прикладная программа - обычно основное окно (main window). Вы создаете основное окно, используя функцию CreateWindowEx, которая определяет класс, имя, стили окна, размер, позицию, дескриптор меню, дескриптор экземпляра и данные для создания. Основное окно принадлежит определяемому приложением классу окна, таким образом, Вы должны зарегистрировать класс окна и предоставить оконную процедуру для класса перед созданием основного окна. Большинство прикладных программ обычно использует для создания основного окна стиль WS_OVERLAPPEDWINDOW. Этот стиль дает окну заголовок, Системное меню (окна), рамку установки размеров, кнопки свертывание и развертывания окна. Функция CreateWindowEx возвращает дескриптор, который уникально идентифицирует окно. Следующий пример создает основное окно, принадлежащее к классу окна определенному прикладной программой. Имя окна, "Основное Окно", появится в строке заголовка окна. Объединяя стилиWS_VSCROLL и WS_HSCROLL со стилем WS_OVERLAPPEDWINDOW, прикладная программа создает основное окно с горизонтальными и вертикальными линейками прокрутки в дополнение к компонентам, предоставляемым стилем WS_OVERLAPPEDWINDOW. Четырехкратное повторение константы CW_USEDEFAULT устанавливает начальный размер и позицию окна в значения, определенные системой по умолчанию. Устанавливая значение ПУСТО (NULL), вместо дескриптора меню, окно получит меню, определенное для класса окна.
Популярное: Почему человек чувствует себя несчастным?: Для начала определим, что такое несчастье. Несчастьем мы будем считать психологическое состояние... Модели организации как закрытой, открытой, частично открытой системы: Закрытая система имеет жесткие фиксированные границы, ее действия относительно независимы... Организация как механизм и форма жизни коллектива: Организация не сможет достичь поставленных целей без соответствующей внутренней... ©2015-2024 megaobuchalka.ru Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. (389)
|
Почему 1285321 студент выбрали МегаОбучалку... Система поиска информации Мобильная версия сайта Удобная навигация Нет шокирующей рекламы |