Разработка программы на ассемблере для Windows
Программирование оконных Windows-приложений, средства TASM для их разработки. Углубленное программирование на ассемблере для Win32, минимальная программа. Организация высокоуровневого консольного ввода-вывода. Наборы символов и функции Wlndows APL.
Рубрика | Программирование, компьютеры и кибернетика |
Вид | курсовая работа |
Язык | русский |
Дата добавления | 23.06.2015 |
Размер файла | 51,6 K |
Отправить свою хорошую работу в базу знаний просто. Используйте форму, расположенную ниже
Студенты, аспиранты, молодые ученые, использующие базу знаний в своей учебе и работе, будут вам очень благодарны.
Размещено на http://www.allbest.ru/
Размещено на http://www.allbest.ru/
Введение
приложение программа консольный
Программирование для операционной системы Windows всегда было занятием не из легких, и на эту тему написано немало книг. Сказать что-то новое довольно трудно, но и обойти эту тему в книге, посвященной одному из языков программирования, на современном этапе развития вычислительной техники было бы не совсем правильно. Сегодня трудно найти компьютер, на котором бы не была установлена одна из версий Windows, если, конечно, на нем не стоит что-то из «мира» UNIX.В подавляющем большинстве книг о программировании для Windows изложение, как правило, ведется на базе языков C/C++, реже - на базе Pascal.
Любая программа на языке самого высокого уровня по сути представляет собой последовательность машинных кодов. А раз так, то всегда остается теоретическая возможность написать ту же программу, но уже на языке ассемблера. Чем можно обосновать необходимость разработки Windows-приложений на языке ассемблера? Приведем следующие аргументы:
- язык ассемблера позволяет программисту полностью контролировать создаваемый им программный код и оптимизировать его по своему усмотрению;
- компиляторы языков высокого уровня помещают в загрузочный модуль программы избыточную информацию, поэтому эквивалентные исполняемые модули, исходный текст которых написан на ассемблере, имеют в несколько раз меньший размер;
- при программировании на ассемблере сохраняется полный доступ к аппаратным ресурсам компьютера;
- приложение, написанное на ассемблере, как правило, быстрее загружается в оперативную память компьютера;
- приложение, написанное на ассемблере, обладает, как правило, более высокой скоростью работы и ответа на действия пользователя.
Разумеется, эти аргументы не следует воспринимать, как некоторую рекламную кампанию в поддержку языка ассемблера. Тем более что компиляторы языков высокого уровня постоянно совершенствуются и подчас способны создавать код, весьма близкий по эффективности к ассемблерному. По этой причине приведенные аргументы не являются бесспорными. И все же нельзя забывать о том, что существует бесконечное множество прикладных задач, ждущих своей очереди на компьютерную реализацию. Далеко не все из этих задач требуют тяжеловесных средств разработки - многие из них могут быть изящно исполнены на языке ассемблера, не теряя привлекательности, например, оконных Windows-приложений.
Целью работы является изучение одного из разделов операционной системы - работа с консольными приложениями.
Выполнение курсовой работы требует самостоятельного изучения программирования на ассемблере под Windows и в конечном итоге написание программы, демонстрирующей усвоение полученных знаний.
1. Разработка Windows-приложений
Вначале нужно выяснить, в чем состоит разница между программированием для DOS и для Windows. Операционные системы MS-DOS и Windows поддерживают две совершенно разные идеологии программирования. В чем разница? Программа DOS после своего запуска должна быть постоянно активной. Если ей, к примеру, требуется получить очередную порцию данных с устройства ввода-вывода, то она сама должна выполнять соответствующие запросы к операционной системе. При этом программа DOS работает по определенному алгоритму, она всегда знает, что и когда ей следует делать.
В Windows все наоборот. Программа пассивна. После запуска она ждет, когда ей уделит внимание операционная система. Операционная система делает это посылкой специально оформленных групп данных, называемых сообщениями. Сообщения могут быть разного типа, они функционируют в системе довольно хаотично, и приложение не знает, какого типа сообщение придет следующим. Отсюда следует, что логика построения Windows-приложения должна обеспечивать корректную и предсказуемую работу при поступлении сообщений любого типа. Тут можно провести определенную аналогию между механизмом сообщений Windows и механизмом прерываний в архи-Программирование оконных Windows-приложений в текстуре IBM PC. Для нормального функционирования своей программы программист должен уметь эффективно использовать функции интерфейса прикладного программирования (Application Program Interface, API) операционной системы.
1.1 Два типа приложений Windows
Windows поддерживает два типа приложений: оконные и консольные.
Оконное приложение строится на базе специального набора функций API, составляющих графический интерфейс пользователя (Graphic User Interface, GUI). Оконное приложение представляет собой программу, которая весь вывод на экран производит в графическом виде. Первым результатом работы оконного приложения является отображение на экране специального объекта - окна. После того как окно появилось на экране, вся работа приложения направлена на то, чтобы поддерживать его в актуальном состоянии.
Не оконное приложение, также называемое консольным, представляет собой программу, работающую в текстовом режиме. Работа консольного приложения напоминает работу программы MS-DOS. Но это лишь внешнее впечатление. Поддержка работы консольного приложения обеспечивается специальными функциями Windows.
Вся разница между двумя типами Windows-приложений состоит в том, с каким типом информации они работают. Основной тип приложений в Windows - оконные, поэтому с них мы и начнем знакомство с процессом разработки программ для этой операционной системы.
1.2 Программирование оконных Windows-приложений
Любое оконное Windows-приложение имеет типовую структуру, основу которой составляет так называемое каркасное приложение, содержащее минимально необходимый для функционирования полноценного Windows-приложения программный код. Не случайно во всех источниках в качестве первого Windows-приложения рекомендуется изучать и исследовать работу некоторого каркасного приложения, так как именно оно отражает основные особенности взаимодействия программы с операционной системой Windows. Более того, написанное и однажды отлаженное каркасное Windows-приложение используется и в дальнейшем в качестве основы для написания любого другого значительно более сложного приложения.
Изложение материала будем иллюстрировать программами на двух языках-C/C++ и ассемблере. Такой подход значительно облегчает понимание технологии написания Windows-приложений на ассемблере. На его основе можно даже выработать некую методику, которая позволит конвертировать многие полезные программы на C/C++ в функционально эквивалентные программы на ассемблере. Перед началом изложения отметим некоторые его характерные черты. Теоретический и практический материал главы будет отражать особенности разработки программ для 32-разрядных операционных систем Windows, к которым относятся Windows 95/98 и Windows NT/2000/XP. Хотя архитектуры этих систем в большей или меньшей степени различаются, их объединяет 32-разрядный программный интерфейс - Win32 API. Он представляет собой функций, к которым может обращаться приложение. Основная идея Win32 API - обеспечение переносимости программ между различными программно-аппаратными платформами.
Для изучения материала этой главы и его практического использования в дальнейшей работе мало иметь только один пакет TASM. Кроме него также необходимы пакеты инструментальных средств разработки приложений на языке C/C++, например от Microsoft или Borland. В том и другом пакетах имеются все необходимые средства для разработки Windows-приложений. Пакет TASM, в отличие от этих пакетов, не обладает такими средствами, поэтому программисту приходится заимствовать их в том или ином виде в пакетах C/C++.
1.3 Каркасное Windows-приложение
Обсуждение вопросов программирования для Windows на ассемблере начнем с обсуждения программы на языке C/C++. Не нужно удивляться такому подходу - «цель оправдывает средства». Нам необходимо, во-первых, понять общие принципы построения оконных Windows-приложений. Во-вторых, разобраться с тем, какие средства ассемблера при этом используются.
Приступая к разработке первого (и не только) Windows-приложения, важно понимать, что сам язык программирования мало влияет на его общую структуру. Это обстоятельство, кстати, и позволит нам чуть позже с относительной легкостью сменить инструментальное средство разработки Windows-приложений с C/C++ на ассемблер.
Минимальное приложение Windows состоит из трех частей:
- главной функции;
- цикла обработки сообщений;
- оконной функции.
Выполнение любого оконного Windows-приложения начинается с главной функции. Она содержит код, осуществляющий настройку (инициализацию) приложения в среде Windows. Видимым для пользователя результатом работы главной функции является появление на экране графического объекта в виде окна. Последним действием кода главной функции является создание цикла обработки сообщений. После его создания приложение становится пассивным и начинает взаимодействовать с внешним миром посредством специальным образом оформленных данных - сообщений. Обработка поступающих приложению сообщений осуществляется специальной функцией, называемой оконной.
Оконная функция уникальна тем, что может быть вызвана только из операционной системы, а не из приложения, которое ее содержит (функция обратного вызова). Тело оконной функции имеет определенную структуру. Таким образом, Windows-приложение, как минимум, должно состоять из трех перечисленных элементов.
Одним из главных критериев выбора языка разработки Windows-приложения является наличие в нем средств, способных поддержать строго определенную последовательность шагов. Язык ассемблера является универсальным языком и пригоден для реализации любых задач, поэтому можно смело предположить, что на нем можно написать также любое Windows-приложение. Но мало написать сам текст Windows-приложения, необходимо знать средства пакета транслятора, специально предназначенные для разработки таких приложений, и уметь пользоваться этими средствами.
1.4 Средства TASM для разработки Windows-приложений
Ранее мы подробно разобрались с тем, что собой представляет простое Windows-приложение, написанное на языке ассемблера. Излагая материал, мы упоминали имена файлов, которые нужны для получения работоспособного исполняемого модуля программы. Для устранения возможных неясностей соберем и систематизируем эту информацию.
При разработке Windows-приложений на языке ассемблера с помощью Win32 API нужен один из пакетов ассемблера - не обойтись без пакета TASM версии 5.0. Современные 32-разрядные операционные системы Windows используют формат РЕ исполняемого файла. В состав пакета TASM 5.0 входят два компилятора ассемблера - 16- и 32-разрядный. Они имеют имена исполняемых файлов, соответственно, tasm.exe и tasm32.exe. То же касается и редакторов связей - tlink.exe и tlink32.exe. Получить файл формата EXE можно только при совместном использовании файлов tasm32.exe и tlink32.exe. Для создания программы нужны еще два файла: файл определений компоновщика и файл описания ресурсов.
Назначение файла определений компоновщика состоит в том, чтобы предоставить редактору связей информацию о способе загрузки программы. Несмотря на то что в архитектуре Win32 нет особого смысла использовать данный файл, редактор tlink32.exe требует указания этого файла среди файлов, подаваемых ему в качестве входных.
Перечислим необходимые для разработки Windows-приложения файлы.
- Файл с исходным текстом программы (.asm). Формируется программистом.
- Включаемый файл с описаниями структур данных и констант
Win32 (.inc или.ash). Файл формируется программистом по мере расширения используемых им средств Win32. Источником информации для этого файла служат включаемые файлы (.h) из пакета компилятора C/C++, например VC++ версии 4.0 и выше.
- Файл с библиотекой импорта import32.lib. Этот файл требуется компоновщику для разрешения внешних ссылок на функции Win32 API. Этот файл можно создать самим. Такая необходимость может возникнуть, если понадобятся функции из библиотек DLL, информация о которых отсутствует в существующем варианте файла import32.lib. Для этого существует специальная утилита implib.exe, поставляемая в пакете TASM 5.O. Командная строка для ее запуска имеет вид
implib имя_файла_li b список_dll_библиотек
Получить информацию о местонахождении конкретной функции Win32 API довольно просто. Многие справочные руководства по Windows при описании конкретной функции приводят и информацию о библиотеке DLL, где эта функция содержится.
- Файл с описанием ресурсов, используемых в приложении.
- Другие файлы. Например, в рассмотренной нами программе каркасного приложения используются звуковые файлы (.wav).
- Файлы tasm32, tlink32.exe и, возможно, некоторые другие вспомогательные файлы из пакета TASM 5.O. Следите внимательно за сообщениями. В том случае, если какого-либо файла будет недоставать, его нужно просто найти в каталоге \bin пакета TASM 5.0 и скопировать в свой рабочий каталог. Непосредственно в каталоге \bin работать не рекомендуется, иначе он моментально превратится в слабоструктурируемое нагромождение файлов.
- Компилятор ресурсов brc32.exe или brcc32.exe. Компиляторы
взяты из пакета C/C++ фирмы Borland. Но если работать с пакетом VC++, то может понадобиться компилятор ресурсов, входящий в этот пакет. Он называется rс.ехе.
- Файл makefile и утилита make.exe. Эти файлы призваны облегчить процесс сборки приложения в единый исполняемый модуль.
Приведенный список файлов, необходимых для сборки Windows-приложения, довольно велик. Ранее процесс получения исполняемого файла у нас был простым и вполне управлялся из командной строки (без использования, например, make-файлов). Более сложные приложения требуют учета взаимосвязей между несколькими файлами. Данные файлы, в свою очередь, создаются или обрабатываются разными программными средствами, которые иногда требуют задания режимов работы многочисленными параметрами. Запоминать их и постоянно вводить вручную тяжело, и такая работа вряд ли может быть признана эффективной. Для облегчения процесса получения исполняемого файла используйте возможности, предоставляемые make-файлами.
Make-файл для программиста - существенное облегчение в его работе. Тщательно разработав один раз make-файл для создания исполняемого файла своегo приложения, вы впоследствии избавите себя от рутинной работы по формированию необходимых для этого командных строк. Второй положительный эффект от использования make-файлов - упрощается работа автора по описанию процесса получения исполняемого модуля.
1.5 Углубленное программирование на ассемблере для Win32
Реализация описанного ранее процесса разработки простого Windows-приложения на языке ассемблера может отнять довольно много сил и времени у неподготовленного человека. Нужно отметить, что объем учебного материала, необходимого для описания процесса разработки каркасного приложения для Windows, не зависит от языка, на котором предполагается вести программирование, так как основное внимание уделяется не столько средствам языка, сколько описанию требований к функционированию приложения со стороны Windows. Каркасное приложение является простейшей программой для Windows, которая в лучшем случае выводит строку текста в окно приложения.
Какими минимальными знаниями и умениями должен обладать программист, чтобы утверждать, что он является, если, конечно, можно так выразиться, профессиональным Windows-программистом? Попытаемся перечислить некоторые проблемы, которые программист должен научиться решать в первую очередь.
- Нужно понять общие принципы построения программы, работа которой управляется сообщениями.
- Нужно научиться выводить текст и графику в область окна приложения. Основная проблема здесь состоит в умении эффективно использовать совокупность средств Win32 API. Сам процесс формирования изображения в окне Windows напоминает процесс формирования изображения в видеобуфере, как это делалось в MS-DOS. Оба эти варианта вывода изображения можно сравнить с рисованием цветными мелками на школьной доске. Для того чтобы обновить содержимое окна, его необходимо либо полностью вывести заново, либо сначала удалить ненужные фрагменты, сформировать на их месте новые и затем вывести в определенное место в окне. Эта проблема называется проблемой перерисовки изображения, и она тесно связана с тем, насколько эффективно решается следующая проблема.
- Нужно организовать адекватную обработку сообщений. Эффективность и правильность работы программы напрямую зависит от того, насколько правильно в ней организована обработка сообщений. В самом начале процесса обучения написанию программ для Windows можно столкнуться с необходимостью обработки такого сообщения, как WM_PAINT. Проблема здесь заключается в том, что Windows не сохраняет содержимое окна или части окна при его свертывании или скрытии под другим окном. Следить за содержимым своих окон должно само приложение, а точнее, соответствующая оконная функция.
- Нужно научиться создавать интерфейсную часть приложения. Интерфейс приложения - это его визитная карточка. Первым, на что обращает внимание пользователь, тем более если он непрофессионал, является именно этот элемент работы приложения. Более того, движущей силой развития самой системы Windows является стремление к реализации идеи идеального интерфейса. На сегодняшний день эту роль играет оконный интерфейс. Что будет завтра, пока не ясно, так как оконный интерфейс действительно решает многие проблемы и до исчерпания его потребительского ресурса, наверное, еще далеко. Основа оконного интерфейса - окно, в котором имеются две области: управляющая, с ее помощью осуществляется управление работой окна, и пользовательская, которая обычно занимает большую часть окна, и именно в ней пользователь формирует некоторое изображение. Управляющая область окна приложения состоит из более элементарных интерфейсных компонентов: меню, окон диалога, кнопок, панелей и т.д. Создание и организация работы со многими из этих компонентов поддерживается Windows с помощью функций Win32 API.
- Нужно научиться обрабатывать пользовательский ввод.
Каждый пункт этого списка представляет лишь вершину некоторой иерархии более частных проблем и может быть довольно глубоко детализирован вглубь.
1.6 Программирование консольных Windows-приложений
Язык ассемблера - язык системных программистов, исследователей принципов работы операционных систем, программ и аппаратных средств. Здесь не всегда нужны красивые графические оболочки, а наоборот, велика потребность в удобных средствах для работы с текстовой информацией. Операционная система Windows обеспечивает встроенную поддержку консолей, которые, по определению, являются интерфейсами ввода-вывода для приложений, работающих в текстовом режиме. Понятие «консоль» существует в вычислительной технике давно. В общем случае под «консолью» подразумевают текстовый терминал для управления компьютером. Видимая часть такого терминала - клавиатура (для ввода управляющих воздействий) и монитор (как средство отображения-реакции вычислительной системы). В Windows консоль представляет собой приложение, которое позволяет взаимодействовать с операционной системой посредством ввода команд. Такой способ управления компьютером позволяет решать в основном административные задачи. Приложение, с помощью которого поддерживается этот режим, называется консольным. Видимая часть консольных приложений называется окном консольного приложения. Написание консольных приложений на ассемблере - задача более актуальная, чем написание оконных. Причина простая - малыми затратами нам становятся доступны практически все возможности Win32 API. Программист может запустить одновременно нескольких консольных приложений и при этом работать с мышью и клавиатурой в стиле Windows. Далее мы рассмотрим порядок действий для запуска консольного Windows-приложения и организацию обмена данными с ним.
API Win32 предоставляет два разных уровня работы с консолью - высокий и низкий. Выбор нужного уровня зависит от того, какая
степень гибкости и полноты контроля требуется приложению для обеспечения своей работы с консолью. Функции высокого уровня обеспечивают простоту процесса ввода-вывода за счет использования стандартных дескрипторов ввода-вывода, но при этом невозможен доступ к входному и экранным буферам консоли. Функции низкого уровня требуют учета большего количества деталей и написания большего объема кода, но это компенсируется большей гибкостью. Консоль состоит из одного входного и нескольких экранных буферов. Входной буфер представляет собой очередь, каждая запись которой содержит информацию относительно отдельного входного события консоли. Экранный буфер - двухмерный массив, содержащий символы, выводимые в окно консоли, и данные об их цвете.
Очередь входного буфера содержит информацию о следующих событиях:
- нажатии и отпускании клавиш;
- манипуляциях мышью - движение, нажатие и отпускание кнопок;
- изменении размера активного экранного буфера, состоянии прокрутки.
С каждой консолью связаны две кодовые таблицы - по одной для ввода и вывода. Консоль использует входную кодовую таблицу для трансляции ввода с клавиатуры в соответствующие символьные значения. Аналогичным образом используется кодовая таблица вывода - для трансляции символьных значений, формируемых различными функциями вывода, в символы, отображаемые в окне консоли.
Для работы с кодовыми таблицами приложение может задействовать пары функций: SetConsoleCP и GetConsoleCP - для входных кодовых таблиц и SetConsoteOutputCP и GetConsoleOutputCP - для выходных кодовых таблиц. Идентификаторы кодовых таблиц, доступные на данном компьютере, сохраняются в системном реестре следующим ключом:
HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Control\\Nls\\CodePage
Для поддержки консольных приложений Win32 API содержит более сорока функций, предназначенных для интеграции в среду Windows программ, работающих в текстовом режиме. Данные функции обеспечивают поддержку отмеченных ранее двух уровней доступа к консоли - высокого и низкого. Консольные функции ввода высокого уровня позволяют приложению извлечь данные, полученные при вводе с клавиатуры и сохраненные во входном буфере консоли. Консольные функции вывода высокого уровня позволяют приложению записать данные в устройство стандартного вывода или в устройство ошибки с тем, чтобы отобразить этот текст в экранном буфере консоли. Функции высокого уровня также поддерживают переназначение стандартных дескрипторов ввода-вывода и управление режимами работы консоли. Консольные функции низкого уровня позволяют приложениям получить детальную информацию о вводе с клавиатуры, событиях нажатия и отпускания кнопок мыши и о манипуляциях пользователя с окном консоли. Все это обеспечивает высокую степень контроля над выводом данных на экран. Высокоуровневый и низкоуровневый консольный ввод-вывод не являются взаимоисключающими, и приложение может использовать любую комбинацию этих функций.
1.7 Минимальная программа консольного приложения
Минимальная программа консольного приложения на ассемблере выглядит так
Листинг
; prg! 6_5.asm
; Пример минимальной программы консольного Windows-приложения
486
model flat, STDCALL; модель памяти flat
include WindowConA.inc
; 0 бъявление внешними используемых в данной программе функций Win32 (ASCII):
extrn AllocConsoleiPROC
extrn SetConsoleTitleA:PROC
extrn ExitProcess:PROC
data
TitleText db 'Win32-console application', 0
code
start proc near; точка входа в программу:
; запрос консоли
call AllocConsole
; проверить успех запроса консоли
test eax.eax
jz exit; неудача
; выведем заголовок окна консоли SetConsoleTitie:
push offset TitleText
call SetConsoleTitleA
; проверить успех вывода заголовка
test eax.eax
jz exit; неудача
;-
; работаем…
;-
exit:; выход из приложения
; готовим вызов VOID ExitProcess (UINT uExitCode)
Push 0
call ExitProcess
start endp
end start
Если убрать комментарии, то кода будет совсем немного. В нем представлены вызовы трех функций: AllocConsole, SetConsoleTitle, ExitProcessю.
Первой функцией консольного приложения должна быть функция запроса консоли AllocConsole:
BOOL A l l o c C o n s o l e (V O I D);
Для вызова функции AllocConsole не требуется никаких параметров. В случае успеха функция AllocConsole возвращает ненулевое значение, при неудаче - нуль. Выделенная консоль представляет собой типичное для Windows окно. Процесс в конкретный момент времени может использовать одну консоль. Если ему нужно запустить еще одну консоль, то прежняя должна быть закрыта или освобождена с помощью функции FreeConsole:
BOOL FreeConsole(VOID);
В случае успеха функция FreeConsole возвращает ненулевое значение, при неудаче - нуль.
При завершении процесса выделенная процессу консоль освобождается автоматически. В нашем случае использован именно этот
вариант закрытия консоли - функцией ExitProcess:
VOID E x i t P r o c e s s (U I N T u E x i t C o d e);
Функции ExitProcess передается код завершения процесса и всех завершаемых цепочек в этом процессе. Проанализировать этот код можно с помощью функций GetExitCodeProcess и GetExitCodeThread. В общем случае в различных ветвях кода может быть несколько точек выхода с вызовом функции ExitProcess. Задавая различные значения кода завершения, можно идентифицировать причину завершения процесса.
Окно консоли может иметь заголовок, для отображения которого предназначена функция SetConsoleTitle:
BOOL SetConsoleTitleUPCTSTR I p ConsoleTitie);
У функции SetConsoleTitle один параметр - указатель на строку с заголовком консоли, заканчивающуюся нулем.
1.8 Организация высокоуровневого консольного ввода-вывода
Для высокоуровневого ввода-вывода приложение может использовать файловые функции ReadFile и Write File, а также функции консольного ввода-вывода ReadConsole и WriteConsole. Эти функции обеспечивают косвенный доступ к входному и экранным буферам пульта. Физически эти функции фильтруют записи входного буфера консоли так, чтобы возвратить ввод как поток символов, игнорируя все другие записи с расширенной информацией о мыши, клавиатуре и изменении размеров окна консоли. Отфильтрованный поток символов отображается в окне консоли, начиная с текущей позиции курсора. Существуют два важных различия в использовании пар функций ReadFile\WriteFile и ReadConsole\WriteConsole.
- Поддержка символов Unicode и ANSI. Консольные функции (ReadConsole\WriteConsole) поддерживают эти наборы, а файловые (ReadFHe\WriteFile) - нет.
- Функции файлового ввода-вывода могут использоваться для обращения как к файлам, так и к именованным каналам (устройствам, присоединенным к последовательному интерфейсу). Консольные функции ввода-вывода можно использовать только с тремя дескрипторами стандартного ввода-вывода.
Из сказанного ранее следует, что функции высокоуровневого ввода-вывода обеспечивают простой способ обмена (чтения-записи) потоков символов с консолью.
Операция чтения высокого уровня реализуется функцией ReadConsole, которая получает входные символы из буфера ввода консоли и сохраняет их в указанном буфере:
BOOL ReadConsole (HANDLE hConsolelnput, LPVOID IpBuffer,
DWORD nNumberOfCharsToRead, LPDWORD IpNumberOfCharsRead,
LPVOID IpReserved);
Параметры этой функции означают следующее:
- hConsolelnput - дескриптор входного потока консоли;
- IpBuffer - указатель на строку, в которую будет записана вводимая строка символов;
- nNumberOfCharsToRead - размер буфера, указанного IpBuffer;
- IpNumberOfCharsRead - количество действительно введенных символов;
- IpReserved - этот параметр не используется, поэтому должен задаваться как NULL
Операция записи высокого уровня реализуется функцией WriteConsole, которая извлекает символы из указанного буфера и записывает их в экранный буфер, на чиная с текущей позиции курсора и продвигая ее по мере записи символов.
BOOL WriteConsole (HANDLE hConsoleOutput, CONST VOID *lpBuffer,
DWORD nNumberOfCharsToWrite, LPDWORD IpNumberOfCharsWritten,
LPVOID IpReserved);
Параметры этой функции означают следующее:
- hConsoleOutput - дескриптор выходного потока консоли;
- IpBuffer - указатель на выводимую строку;
- nNumberOfCharsToWrite - размер буфера, указанного IpBuffer;
- IpNumberOfCharsWritten - количество действительно выведенных символов;
- IpReserved - этот параметр не используется, поэтому должен задаваться как NULL.
Для своей работы эти и некоторые другие консольные функции требуют получения стандартных дескрипторов ввода-вывода. Значения этих дескрипторов присваиваются параметрам hConsolelnput и hConsoleOutput. По умолчанию стандартный дескриптор ввода связан с клавиатурой, стандартный дескриптор вывода - с экраном. Получить стандартный дескриптор ввода-вывода можно с помощью функции GetStdHandle.
HANDLE GetStdHandle (DWORD nStdHandle);
На вход функции GetStdHandle должно быть подано одно из следующих значений:
- STD_INPUT_HANDLE = -10 - дескриптор стандартного входного потока;
- STD_OUTPUT_HANDLE = -11 - дескриптор стандартного выходного потока;
- STD_ERROR_HANDLE = -12 - дескриптор стандартного потока ошибок.
Используя функции высокоуровневого ввода-вывода, приложение может управлять цветами текста и фона, которыми должны отображаться символы, записываемые в экранный буфер. Приложению доступны следующие функции высокоуровневого консольного ввода-вывода:
- эхо-контроль вводимых символов на экране из активного экранного буфера;
- ввод строки, окончание операции чтения которой происходит при
- нажатии клавиши Enter;
- автоматическая обработка некоторых символов, вводимых с клавиатуры: перевода каретки, нажатия клавиш Ctrl+C и т.д.;
- автоматическая обработка некоторых символов, выводимых на экран: перевода строки и каретки, возврата на один символ и т.д.
Функция SetConsoleCursorPosition предназначена для указания позиции, с которой начинается выполнение операций чтения-записи в окно консоли:
BOOL SetConsoleCursorPosition (HANDLE hConsoleOutput,
COORD dwCursorPosition);
Параметрами этой функции являются стандартный дескриптор вывода hConsole-Output, полученный функцией GetStdHandle, и указатель на структуру COORD с координатами новой позиции курсора:
COORD struc
х dw 0
у dw О
ends
По умолчанию цветовое оформление окна консоли довольно унылое - черный фон, белый текст. Внести разнообразие во внешний вид окна консоли поможет функция SetConsoleTextAttribute, с помощью которой можно изменить цвета, установленные по умолчанию для текста и фона:
BOOL SetConsoleTextAttribute (HANDLEhConsoleOutput, WORD w Attributes)
Первый параметр - без комментариев, второй определяет цвет текста и фона. Второй параметр формируется через операцию логического ИЛИ следующих значений:
- FOREGROUND_BLUE = OOOlh - синий текст;
- FOREGROUND_GREEN = 0002h - зеленый текст;
- FOREGROUND_RED = 0004h - красный текст;
- FOREGROUNDJNTENSITY = 0008Н - текст повышенной яркости;
- BACKGROUND_BLUE = OOlOh - голубой фон;
- BACKGROUND_GREEN = 0020h - зеленый фон;
- BACKGROUND_RED = 0040И - красный фон;
- BACKGROUNDJNTENSITY = OOSOh - фон повышенной яркости.
Для задания белого цвета складываются три цветовых компонента, для задания черного компоненты не задаются вовсе.
1.9 Работа с консолью в среде Windows
Windows поддерживает работу двух типов приложений - оконных, в полной мере использующих все достоинства графического интерфейса, и консольных, работающих исключительно в текстовом режиме. Поэтому не следует путать понятие «консоли» с понятием «консольного приложения» Windows. В предшествующем материале под «консолью» подразумевались средства для ввода информации с клавиатуры и вывода ее на экран. Для однозначности изложения далее под термином «консоль» мы будем иметь в виду либо само консольное приложение, либо его видимую часть - окно консольного приложения.
Организация низкоуровневого консольного ввода-вывода
Низкий уровень консольного ввода-вывода, по сравнению с высоким уровнем, обладает более широкими и гибкими возможностями. Низкоуровневые функции консольного ввода-вывода обеспечивают прямой доступ к входному и экранным буферам консоли, предоставляя приложению доступ к событиям мыши и клавиатуры, а также к информации об изменении размеров окна консоли. Функции низкоуровневого ввода-вывода позволяют приложению иметь доступ по чтению-записи к указанному числу последовательных символьных ячеек в экранном буфере или к прямоугольному блоку символьных ячеек в указанной позиции экранного буфера.
2. Создание терминальных приложений на ассемблере для Windows
При запуске любого приложения в системе Windows для него создается либо текстовое (терминальное), либо графическое окно. Для создания терминального приложения при компоновке программы необходимо указать в командной строке программы LINK указанную ниже опцию (мы используем ее командном файлетаке32. bat):
/SUBSYSTEM:CONSOLE
Как мы уже говорили, терминальные приложения внешне очень похожи на программы, написанные для системы MS DOS.
В терминальных программах данные читаются со стандартного устройства ввода, а выводиться информация может либо на стандартное устройство вывода, либо на стандартное устройство вывода сообщений об ошибках. Для терминального приложения создается один входной буфер и один или несколько буферов для вывода на экран, как описано ниже.
- Входной буфер состоит из очереди входных записей, каждая из которых содержит информацию об одном событии, поступившем от какого-либо устройства ввода. В качестве примеров таких событий можно привести нажатие на клавишу на клавиатуре, щелчок кнопкой мыши либо изменение пользователем размеров терминального окна.
- Буфер экрана представляет собой двумерный массив, элементы которого содержат данные и атрибуты, влияющие на внешний вид текста, отображаемого на экране терминала.
2.1 Наборы символов и функции Wlndows APL.
В системе Windows предусмотрены два типа наборов символов, которые можно использовать при вызове функций Win32 API: 8-разрядные символьные наборы стандарта ASCII/ANSI и расширенные 16-разрядные символьные наборы стандарта Unicode, применяемые в системах Windows NT, 2000 и XP.
Поэтому для работы с текстовыми данными существует два набора одинаковых функций Windows API, отличающихся в названии только последней буквой. Функции, оканчивающиеся на букву «А», обрабатывают 8-разрядные ASCII-строки, а если название функции заканчивается на букву «W» (от английского слова mde, или расширенный), они обрабатывают 16-разрядные расширенные наборы символов, включая стандарт Unicode.
Один изпpимepoв-фyнкция WriteConsole:
* WriteConsoleA;
* WriteConsoleW.
Функции, название которых оканчивается на букву «w», не поддерживаются в системах Windows 95 и 98. С другой стороны, в системах Windows NT, 2000 и XP стандартным набором символов считается Unicode. Поэтому при вызове в них функций, таких как WriteConsoleA, операционная система сначала конвертирует текстовую строку из формата ANSI в формат Unicode, а затем вызывает функцию WriteConsoleW.
В документации по Microsoft MSDN в именах функций, таких как WriteConsole, последняя буква «А» или «w» не указывается.
Высокоуровневый и низкоуровневый доступ. Для обеспечения компромисса между простотой использования и полнотой управления предусмотрено два уровня доступа к терминальным функциям.
- Терминальные функции высокого уровня обеспечивают чтение потока символов из входного буфера, а также запись данных в буфер экрана терминала. Оба потока данных (входной и выходной) могут быть перенаправлены, так чтобы чтение и запись данных производилась в текстовые файлы.
- Терминальные функции низкого уровня позволяют получить детальную информацию о событиях, поступивших от клавиатуры или мыши, а также определить, какие действия над окном терминала выполнил пользователь (например, перетаскивание, изменение размера и т.п.). С помощью этой группы функций в программе можно также задать размер и положение окна терминала, а также цвет отображаемых символов.
Листинг программы
3.exe
686; Директива определения типа микропроцессора
Model flat, stdcall; задачи линейной модели памяти
; И соглашения ОС Windows
option casemap: none; отличие малых и больших букв
include \masm32\include\windows.inc
include \masm32\include\kernel32.inc
include \masm32\include\fpu.inc
include \masm32\include\user32.inc
includelib \masm32\lib\user32.lib
includelib \masm32\lib\kernel32.lib
includelib \masm32\lib\fpu.lib
ExitProcess proto: DWORD
DATA; директива определения данных
st1 db «Вывод суммы массива! А», 0
st2 db 10 dup (?), 0
ifmt db «Сумма =% d», 0
masivA db 75,31,88,32
sum dw 0
iden db 0
work1 db 0
work2 db 0
prom dd 0
Code; директива начала кода
_start:
mov eax, 0
mov ebx, 0
mov ecx, 3
mov edx, 0
lea esi, masivA
M1:
mov prom, ebx
mov al, byte ptr [esi + ebx]; пересылки значения массива в младший регистр al
inc ebx
mov bl, byte ptr [esi + ebx]; пересылки значения массива в младший регистр bl
mov work1, al
mov work2, bl
and eax, 21h
and ebx, 21h
sub eax, ebx; проверка сходимости битов
jz M3
mov iden, 0; идентификатор. Он необходим для суммы.
M2:
mov ebx, prom
inc ebx
loop M1
jmp M4
M3:
mov al, work1
dec iden
jz Q1; если идентификатов = 0, тогда перейти на метку Q1
mov iden, 1
mov bl, work2
Q1: add sum, ax; подсчета суммы
add sum, bx; подсчета суммы
jmp M2
M4:
mov ebx, 0
mov bx, sum; пересылка значение суммы в регистр
invoke wsprintf, ADDR st2, ADDR ifmt, ebx
invoke MessageBox, NULL, addr st2, addr st1, MB_OK; функция вывода значения
invoke ExitProcess, 0
end _start; окончания программы
2.exe
686; Директива определения типа микропроцессора
Model flat, stdcall; задачи линейной модели памяти
; И соглашения ОС Windows
option casemap: none; отличие малых и больших букв
include C:\masm32\include\windows.inc
include C:\masm32\include\kernel32.inc
include C:\masm32\include\fpu.inc
include C:\masm32\include\msvcrt.inc
include C:\masm32\include\user32.inc
includelib C:\masm32\lib\user32.lib
includelib C:\masm32\lib\kernel32.lib
includelib C:\masm32\lib\msvcrt.lib
includelib C:\masm32\lib\fpu.lib
include C:\masm32\include\windows.inc
include C:\masm32\include\kernel32.inc
include C:\masm32\include\fpu.inc
include C:\masm32\include\user32.inc
include C:\masm32\include\msvcrt.inc
includelib C:\masm32\lib\user32.lib
includelib C:\masm32\lib\kernel32.lib
includelib C:\masm32\lib\msvcrt.lib
includelib C:\masm32\lib\fpu.lib
Data; директива определения данных
frmt db «% d», 0
buf db 30 dup (0)
buf2 db 20 dup (0)
stdout db «% d», 0
stdin db «% d», 0
const dd 10
temp1 dd 0.0
temp2 dd 0.5
temp3 dd 0.5
temp4 dd 0.5
identif1 dd 1
identif2 dd 1
st1 db «Vvedyte a», 0
st2 db «Vvedyte b», 0
st3 db «Результат вычисления a + b», 0
st4 db «a + b =», 0
Code; директива начала кода
start:
invoke GetStdHandle, STD_OUTPUT_HANDLE
lea eax, stdout
invoke GetStdHandle, STD_INPUT_HANDLE
lea eax, stdin
invoke WriteConsoleA, stdout, ADDR st1, 11, NULL, NULL; VIVOD ST1
invoke ReadConsole, stdin, ADDR buf, 20, ADDR st2, NULL; чтения числа как символ
invoke crt_atoi, ADDR buf; преобразовать символ в число
mov temp1, eax
lea edi, buf
mov ecx, 30
m1:
mov al, '.'
mov bl, [edi]
xor al, bl
jz m2
inc edi
loop m1
m2:
lea esi, buf2
mov ecx, 20
m3:
inc edi
mov ebx, [edi]
mov [esi], ebx
inc esi
loop m3
invoke crt_atoi, ADDR buf2; преобразовать символ в число
mov temp2, eax
id1:
mov eax, identif1
mov ebx, const
mul ebx
SHL edx, 16; делаем сдвиг на 16
mov dx, ax
mov identif1, edx
mov ecx, temp2
sub ecx, edx
jc id_end1
jmp id1
id_end1:
invoke GetStdHandle, STD_OUTPUT_HANDLE
lea eax, stdout
invoke GetStdHandle, STD_INPUT_HANDLE
lea eax, stdin
invoke WriteConsoleA, stdout, ADDR st1, 11, NULL, NULL; VIVOD ST1
invoke ReadConsole, stdin, ADDR buf, 20, ADDR st2, NULL; чтения числа как символ
invoke crt_atoi, ADDR buf; преобразовать символ в число
mov temp3, eax
lea edi, buf
mov ecx, 30
m4:
mov al, '.'
mov bl, [edi]
xor al, bl
jz m5
inc edi
loop m4
m5:
lea esi, buf2
mov ecx, 20
m6:
inc edi
mov ebx, [edi]
mov [esi], ebx
inc esi
loop m6
invoke crt_atoi, ADDR buf2; преобразовать символ в число
mov temp4, eax
id2:
mov eax, identif2
mov ebx, const
mul ebx
SHL edx, 16; делаем сдвиг на 16
mov dx, ax
mov identif2, edx
mov ecx, temp4
sub ecx, edx
jc id_end2
jmp id2
id_end2:
finit
fild temp1
fiadd temp3
fild temp2
fidiv identif1
fadd st (0), st (1)
fild temp4
fidiv identif2
fadd st (0), st (1)
invoke FpuFLtoA, 0, 10, ADDR st4, SRC1_FPU or SRC2_DIMM
invoke MessageBox, NULL, addr st4, addr st3, MB_OK
invoke ExitProcess, NULL; возврат управления Windows
; И освобождения ресурсов
end start; директива окончания программы с именем start
Заключение
Разработка Windows-приложения на языке ассемблера - вполне реальное и в ряде случаев оправданное дело. Однако, несмотря на имеющиеся в TASM и MASM средства, для создания полноценного Windows-приложения требуются дополнительные программные и информационные ресурсы, предоставляемые пакетами языков высокого уровня. Лучше всего для этой цели подходит пакет VC++ версии 6.0 и выше. Основную ценность в нем имеют включаемые файлы, редактор ресурсов, работающий в составе интегрированной среды разработки, и компилятор ресурсов. Интерес могут представлять также различные утилиты, входящие в состав пакета VisualC++, например Spy++.
Приступать к разработке приложения для системы Windows на ассемблере лучше всего, имея некоторый опыт разработки приложений на языке высокого уровня. Это необходимо для понимания логики работы приложения. Когда понимание логики работы Windows-приложения достигнуто, выбор языка для его реализации приобретает в большей степени техническое значение и определяется постановкой задачи и предполагаемыми условиями ее эксплуатации.
Благодаря поддержке системой Windows консольных приложений можно малыми силами решать серьезные задачи, в том числе и по администрированию системы. Консольным приложениям доступны практически все возможности, предоставляемые Win32 API, при этом для построения приложений не требуется реализовывать какие-то изощренные схемы.
Список используемой литературы
1. Юров В.И. Ассемблер: Учебник для вузов. - СПб.: Питер, 2003. - 637 с.
2. Юров В.И. Ассемблер. Практикум. 2-е изд. - СПб.: Питер, 2006. - 399 с.
3. http://www.assembler.webservis.ru
4. http://www.kalashnikoff.ru
5. http://www.vlata.com
6. СА Майоров, ВВ Кириллов, АА Приблуда Введение в микро-ЭВМ
7. Калашников О.А. Ассемблер? Это просто! Учимся программировать. - СПб.: БХВ - Петербург, 2006. - 384 с.
8. Магда Ю.С. Ассемблер для процессоров Intel Pentium. - СПб.: Питер, 2006. - 410 с.
9. В.Ю. Пирогов. Assembler. Учебный курс.: М., 2001.
10. Марек Р. Ассемблер на примерах. Базовый курс. - СПб.: Наука и техника, 2005. - 240 с.
11. Фролов А.В., Фролов Г.В. Библиотека системного программиста. Т. 1. Часть 1, 2, 3. Операционная система MS-DOS. М: ДИАЛОГ-МИФИ, 1991, 1993
12. Рудаков П.И., Финогенов К.Г. Язык ассемблера: уроки программирования. - М.: ДИАЛОГ-МИФИ, 2001. - 640 с.
13. Ирвин, Кип. Язык ассемблера для процессоров Intel, 4-е издание.: Пер. с англ. - M.: Издательский дом «Вильямс», 2005. - 912 с.
14. Питер Абель, Ассемблер и программирование для IBM PC, Пер. с англ. - Технологический институт Британская Колумбия
Размещено на Allbest.ru
Подобные документы
Таймер в Windows как устройство ввода информации, которое извещает приложение о том, что истек заданный интервал времени. Работа с таймером в условиях WinAPI, процесс 32-битного программирования на ассемблере под Windows. Результат выполнения программы.
курсовая работа [165,6 K], добавлен 18.05.2014Создание и компиляция программ на ассемблере. Структура программ, использование специальных директив резервирования и инициализации данных. Организация ввода-вывода на ассемблере и организация вычислений. Команды передачи управления и обработки строк.
методичка [104,8 K], добавлен 02.12.2009Введение в API-программирование. Структура API-программ. Организация ввода-вывода в консольном приложении Windows. Организация низкоуровнего консольного ввода-вывода. Расширенная поддержка клавиатуры в консоли. Поддержка работы с мышью в консоли.
курсовая работа [91,0 K], добавлен 10.02.2015Введение в API-программирование. Транслирование клавиатурных сообщений в ASCII-коды. Текст программы на 32-битном ассемблере с применением API-функций. Функция для создания диалогового окна. Определение открываемого диска, каталога и имени файла.
курсовая работа [40,6 K], добавлен 18.05.2014Основы программирования на 32-битном Ассемблере, разработка с его помощью программы, демонстрирующей работу одного из разделов ОС Windоws. Описание используемых АРI-функций как интерфейса программирования приложений. Листинг программы, результаты работы.
курсовая работа [164,5 K], добавлен 18.05.2014Ассемблер как символический аналог машинного языка. Архитектура микропроцессора: организация памяти, способы адресации операндов, правила использования регистров. Текст программы. Этапы программирования на ассемблере, алгоритмы выполнения задач.
контрольная работа [515,1 K], добавлен 20.01.2016Основные характеристики графики в операционной системе Windows, реализация объектно-ориентированной идеологии. Специфика и этапы разработки программного продукта, описывающего графический объект, на 32-битном ассемблере с использованием API-функции.
курсовая работа [82,3 K], добавлен 18.05.2014Основы работы с многооконным графическим пользовательским интерфейсом операционной системы Windows95/NT. Основы работы с прикладными программами Windows и DOS. Разработка простого приложения для Windows при помощи средства разработки приложений DELPHI.
контрольная работа [281,0 K], добавлен 15.01.2009Структурное программирование, схема алгоритма. Программа на языке Си для int, float. Подпрограмма ввода и вывода целых чисел на Ассемблере IBM. Тестирование и отладка, инструкция пользователя. Язык программирования Си (для int и float), этапы трансляции.
курсовая работа [1,5 M], добавлен 21.10.2014Приемы и правила объектно-ориентированного программирования с использованием языка С++. Общие принципы разработки объектно-ориентированных программ. Основные конструкции языка С++. Разработка различных программ для Windows с использованием WIN32 API.
учебное пособие [1,6 M], добавлен 28.12.2013