Введение
Эволюция средств проектирования программ в течение последних десятилетий способна удивить любого человека, занимающегося разработкой программного обеспечения. Особенно это касается написания программ для операционных систем семейства Windows. Современные инструментальные средства настолько развиты, что разработчик программного обеспечения может получить готовую программу с помощью нескольких щелчков мышью. Огромное количество книг, статей и исходных текстов программного кода посвящено проектированию программ на С, Pascal, Basic и других языках программирования. Язык низкого уровня — язык ассемблера — после "смерти" MS-DOS, казалось, доживает последние дни. Но вопреки прогнозам он не сошел с арены и продолжает весьма широко использоваться при разработке программ. В чем же секрет живучести этого языка?
Ответ довольно прост и может быть сформулирован одним предложением: язык ассемблера — это язык, на котором "говорит" процессор, и исчезнуть он может только вместе с исчезновением процессоров! По этой же причине ассемблер имеет одно фундаментальное преимущество перед языками высокого уровня: он самый быстрый. Большинство приложений, работающих в режиме реального времени, либо написаны на ассемблере, либо используют в критических участках кода ассемблерные модули.
Нередко можно слышать утверждения о том, что процесс разработки программ на языке ассемблера слишком трудоемок и отнимает массу времени. Еще одним препятствием для работы с ассемблером считают его сложность. И, наконец, в качестве аргумента приводится утверждение, что разработка приложений на ассемблере сильно затруднена из-за отсутствия современных инструментальных средств для проектирования и отладки.
Такие утверждения, вообще-то, не соответствуют действительности. Язык ассемблера не сложнее других языков программирования и довольно легко осваивается как опытными, так и начинающими программистами. Кроме того, в последние годы появились очень мощные инструментальные средства разработки программ на ассемблере, и это вынуждает по-другому взглянуть на процесс разработки программ на этом языке. Среди таких инструментальных средств проектирования можно назвать макроассемблер MASM32, AsmStudio и NASM. Эти и другие аналогичные инструменты проектирования сочетают в себе гибкость и быстроту ассемблера и современный графический интерфейс. Многочисленные библиотеки функций, разработанные для ассемблера, приблизили этот язык по своим функциональным возможностям к средствам проектирования приложений на языках высокого уровня. Поэтому в настоящее время противопоставление ассемблера языкам высокого уровня не имеет под собой реальных оснований.
Глава 1. Теоретическая часть Использование Ассемблера для разработки Windows-приложений
Несмотря на то, что ассемблер воспринимается многими программистами только как вспомогательное средство для улучшения программ, его значение как самостоятельного средства разработки высокоэффективных приложений в последнее время очень изменилось.
До сих пор существует некий стереотип, касающийся разработки приложений на ассемблере. Среди многих программистов, пишущих на языках высокого уровня, бытует мнение о сложности ассемблера, плохой структурируемости программного обеспечения и плохой переносимости кода при переходе на другие платформы. Возможно, многие помнят разработку программ на ассемблере в MS-DOS, что действительно требовало немалых усилий. Кроме того, отсутствие в то время современных средств программирования на ассемблере замедляло разработку сложных проектов.
В последнее время ситуация изменились благодаря появлению принципиально новых и эффективных средств быстрой разработки на языке ассемблера. Специально для этого были разработаны мощные средства быстрого проектирования (Rapid Application Development — RAD), такие как MASM32, Visual Assembler, RADASM. Размер и быстродействие оконного приложения SDI (single-document interface), написанного на ассемблере, просто впечатляет.
Такие средства разработки имеют, как правило, компиляторы ресурсов, большие библиотеки готовых к использованию функций и мощные средства отладки. Можно смело утверждать, что разработка программ на ассемблере стала столь же легкой, как и на языках высокого уровня.
Основная причина, по которой ассемблер не применялся массово для разработки программ, — отсутствие средств быстрого проектирования — исчезла. Какие приложения можно проектировать на ассемблере? Проще ответить на другой вопрос — что не следует писать на ассемблере? Небольшие и средние по объему 32-разрядные приложения для Windows можно целиком написать на ассемблере. Однако если разрабатывать сложную программу, требующую применения самых современных технологии, то лучше использовать языки высокого уровня с последующей оптимизацией отдельных участков кода на ассемблере.
Существует еще одна проблема использования ассемблера, связанная с тем, что этот язык рассчитан на разработку процедурно-ориентированных приложений и не использует методы объектно-ориентированного программирования (ООП). Именно это приводит к некоторым ограничениям при использовании ассемблера. Тем не менее это никак не мешает применять язык ассемблера для написания классических Windows-приложений процедурно- ориентированного типа.
Современные средства разработки программ на ассемблере не только позволяют создать графический интерфейс пользователя, но и сохраняют фундаментальное преимущество ассемблера: фантастически малый размер исполняемого модуля. Короткие быстрые приложения на ассемблере находят применение там, где размеры кода и его быстродействие являются критическими параметрами. Сферами применения таких приложений являются системы реального времени, системные утилиты и программы, а также драйверы устройств.
Программы на ассемблере управляют как периферийным оборудованием персонального компьютера (ПК), так и нестандартными устройствами, присоединенными к ПК. Минимальные размеры программного кода обеспечивают высокое быстродействие работы таких устройств. Приложения реального времени используются повсеместно в системах управления в промышленности, научных и лабораторных исследованиях, в военных разработках.
Особенность системных программ и утилит состоит в том, что они очень тесно взаимодействуют с операционной системой, и скорость выполнения таких приложений может существенно повлиять на общую производительность всей системы. Это в значительной степени относится и к разработке драйверов периферийных устройств компьютера и системных служб. Средства разработки на ассемблере позволяют создавать и быстрые утилиты командной строки (консольные приложения). Использование в таких утилитах системных вызовов Windows позволяет выполнить очень многие сложные функции (копирование файлов, функции поиска и сортировки, обработка и анализ математических выражений и т.д.) с очень высоким быстродействием.
Другой важной областью применения ассемблера является разработка драйверов нестандартных и специализированных устройств, управляемых при помощи ПК. В таких случаях использование программ на языке ассемблера будет очень эффективным. Примеров такого применения ассемблера можно привести много. Это и системы обработки данных на базе ПК с использованием выносных устройств, одноплатные компьютеры с флэш-памятью, системы диагностики и тестирования различного оборудования.
Необходимо также упомянуть еще об одном аспекте применения языка ассемблера, достаточно экзотическом, но тем не менее используемом. Основная программа пишется на ассемблере, а вспомогательные модули — на любом другом языке, например на С++ или Pascal. При этом основная программа использует, как правило, мощные библиотечные функции языка высокого уровня, например математические или строковые. Кроме того, если для разработки интерфейса используются вызовы WIN API (Application Programming Interface), то программа получится очень мощной. Конечно, написание таких программ требует от программиста незаурядных знаний ассемблера и языков высокого уровня.
Глава 2. Практическая часть
На этапе постановки задачи были поставлены следующие условия:
Создать Windows-приложение на языке Ассемблер.
Далее нужно было выбрать номер варианта задания:
Номер задания равен: (N % 43) + 1, где N – номер зачетки (в данном случае 100046).
Сделав приведенные выше вычисления, получили вариант №29.
Текст варианта задания: Сделать программу преобразователь текста.
Исходный код программы
.386
.model flat, stdcall
option casemap :none
include \masm32\include\windows.inc
include \masm32\include\user32.inc
include \masm32\include\kernel32.inc
includelib \masm32\lib\user32.lib
includelib \masm32\lib\kernel32.lib
.data
conTitle DB " Convert to program", 0 ;задаем текст окна
mes1 DB " Before: ",0 ;в mes1 переменую записуем слово
len_mes1 EQU $-mes1
mes2 DB " After: ", 0 ;в переменую mes2 записуем слово
len_mes2 EQU $-mes2
S1 DB "hello word!",0dh,0ah,0 ;вводим строку для конвертирования
LS1 EQU $-S1
charBuf DB " ",0
len_charBuf DD $-charBuf
readBuf DB ?
lenReadBuf DD 1
hStdIn DD 0
hStdOut DD 0
chrsRead DD 0
chrsWritten DD 0
STD_INP_HNDL DD -10
STD_OUTP_HNDL DD -11
.code
start:
call AllocConsole ;вызов консоли
test eax, eax ;логическая И с eax
jz ex ;переход на ex
push offset conTitle ;задаем титульное заглавие
call SetConsoleTitleA ;изменяем название консоли
test eax, eax ;логическая И
jz ex ;переход на ex
call getout_hndl ;вызов getout_hndl
call getinp_hndl ;вызов getinp_hndl
push EBX ;задаем EBX
mov EBX, offset mes1 ;записуем в EBX mes1
mov ECX, len_mes1 ;в ECX записуем длину mes1
call write_con ;добавляем консоль
pop EBX ;меняем значение EBX старое знач. утрачиваеться
push EBX ;изменяем EBX
mov EBX, offset S1 ;записуем в EBX строку которую будем конвертировать
mov ECX, LS1 ;в ECX записуем длину строки S1
call write_con ;добавляем в консоль
pop EBX ;меняем значение EBX старое знач. утрачиваеться
push EBX ;изменяем EBX
mov EBX, offset mes2 ;записуем в EBX строку mes2
mov ECX, len_mes2 ;записуем в ECX длину mes2
call write_con ;добавляем в консоль
pop EBX ;меняем значение EBX старое знач. утрачиваеться
lea ESI, dword ptr S1 ;в ESI содержит указатель на S1
mov ECX, dword ptr LS1 ;в ECX помещаем длину S1
next:
mov AL, BYTE PTR [ESI] ;записуем в AL байтовое значение ESI
cmp al, 'a' ;сравниваем AL с буквой
jb next_addr ;переход на метку next_addr
cmp AL, 'z' ;сравниваем AL с буквой
ja next_addr
and AL, 0dfh ;логическое умножение между AL и 0dfh строчные в заглавные
mov BYTE PTR [ESI], AL ;записуем баутовое значение ESI в AL
next_addr:
inc ESI ;ESI увеличим на 1
loop next ;повторить next
push EBX ;изменяем EBX
mov EBX, offset S1 ;записуем в EBX S1
mov ECX, LS1 ;записуем в ECX длину S1
call write_con ;добавляем в сонсоль
pop EBX ;меняем значение EBX старое знач. утрачиваеться
call read_con ;редактируем консоль
ex:
push 0
call ExitProcess ;закрываем процес
;------ functions ----
getout_hndl proc ;getout_hndl процесс
push STD_OUTP_HNDL ;изменяем STD_OUTP_HNDL
call GetStdHandle ;добавляем GetStdHandle
mov hStdOut, eax ;в hStdOut записуем eax
ret ;уменьшение указателя стека на 2
getout_hndl endp ;закрываем процесс
getinp_hndl proc
push STD_INP_HNDL
call GetStdHandle
mov hStdIn, eax
ret
getinp_hndl endp
write_con proc
push 0 ;lpReserved = NULL
push chrsWritten ;число байтов написаны на StdOut
push ECX
push EBX
push hStdOut
call WriteConsoleA
ret
write_con endp
read_con proc
push 0 ;lpReserved = NULL
push chrsRead
push lenReadBuf
push offset readBuf
push hStdIn
call ReadConsoleA
ret
read_con endp
;-------------------
end start
Выводы
В ходе выполнения курсовой работы было получено работоспособное Windows-приложение в результате выполнения которого программа, по вводу строки может изменять буквы нижнего регистра в буквы верхнего регистра. Данная программа может быть использована, как уже указывалось ранее, для преобразования текста. Разработанная программа соответствует всем условиям, поставленным на этапе постановки задачи.
