Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
2012- СИСПРОГ на МАСМ.doc
Скачиваний:
21
Добавлен:
09.11.2019
Размер:
553.47 Кб
Скачать

4.3Выполнение работы

  1. Откройте в QE файл \MASM32\examples\exampl02\textio\ textio.asm и пересохраните его в свою рабочую папку под именем lab4.asm. Он будет подвергаться дальнейшему анализу и комментированию, поэтому исходный файл textio.asm портить не надо.

  2. Выполните Project > Console Assemble & Link. Просмотрите, что выведено в окно консоли с протоколом компиляции и компоновки. Нет ли сообщений об ошибках? Выполните Project > Run Program.

  3. После приглашения Enter Some Text > вы что-то напечатали и на следующей строке программа повторила ваш ввод эхо-выводом. Ниже появилось приглашение Type something > и вы опять что-то напечатали. Что произошло после нажатия Enter?

  4. Перейдите в lab4.asm на строки 94-96. Изучив текст программы, определите, что должно делаться строками 94-96. А вы видели эти результаты при исполнении программы? Сформулируйте для отчета возможную причину наблюдаемого эффекта.

  5. Откройте \MASM32\m32lib\stdout.asm и распечатайте его для отчета.

  6. Откройте \MASM32\m32lib\stdin.asm и распечатайте его для отчета.

  7. Имея перед глазами файлы stdout.asm и stdin.asm, подробно построчно прокомментируйте файл lab4.asm.

  8. Письменно ответьте на контрольные вопросы. Писать сначала текст вопроса, затем ответ на него.

  9. Оформить отчет по лабораторной работе.

4.4Состав отчета по работе

  1. Название и номер работы, фамилия и группа студента.

  2. Цель работы.

  3. Протокол выполнения работы с текстами ответов на все вопросы в заданиях пункта «Выполнение работы».

  4. Ответы на контрольные вопросы.

  5. Личная подпись автора отчета.

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

  1. Каково назначение макроса print в файле lab4.asm? Контейнером какой процедуры он является? В чем удобство использования print?

  2. Каково назначение макроса input? Опишите словами, что происходит в программе при исполнении команд макроса input? В чем состоит удобство его применения?

  3. В строке 50 написано «Main PROTO». Что это значит и зачем это нужно?

  4. В строках 90 и 94 вызывается процедура locate. Используя файл \MASM32\m32lib\locate.asm, определите, какую функцию WinAPI она инкапсулирует? Найдите в MSDN (можно в другом источнике) ее описание приведите его в отчете.

5Ввод и вывод в ассемблерных приложениях с графическим интерфейсом

5.1Цель работы

Изучить технику использования элементов графического пользовательского интерфейса (Graphic User Interface, GUI), которые применимы для ввода данных в программу и вывода текстов.

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

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

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

Типичную структуру папки ассемблерного приложения с GUI можно увидеть, например, в MASM32\examples\dialogs_later\basic. Откройте ее. В ней содержатся файлы:

  • basicdlg.asm – текст программы на МАСМ;

  • basicdlg.ico – файл иконки программы;

  • manifest.xml – файл «манифеста»;

  • rsrc.rc – ресурсный файл.

Эти файлы представляют собой настоящий набор «исходных файлов», из которых с помощью пакетного файла makeit.bat создается исполняемый модуль basicdlg.exe.

Файлы basicdlg.asm, manifest.xml, rsrc.rc и makeit.bat можно открыть и просмотреть текстовым редактором, лучше всего Notepad++. Файл basicdlg.ico можно просмотреть, например, через Paint. Что делает программа в целом, можно увидеть, просто запустив basicdlg.exe.

Файлы basicdlg.ico, manifest.xml и rsrc.rc – вспомогательные. Они поставляют программе информацию и данные, необходимые для правильного показа элементов GUI. Главным среди них является ресурсный файл rsrc.rc. Откройте его и обратите внимание на строчки

1 24 "manifest.xml"

5 ICON "basicdlg.ico"

Этими строками вспомогательные ресурсы программы связываются воедино – ресурсный файл содержит в себе ссылки на иконку и на файл манифеста.

Для чего нужна иконка (файл basicdlg.ico) и как она создается, студент 2-го курса компьютерной специальности, скорее всего, знает. А вот что касается файла манифеста manifest.xml, то, скорее всего, такой ясности нет и надо сделать необходимые пояснения.

Манифест (manifest) - это текст на языке XML, описывающий программу и графические библиотеки, необходимые для ее работы. До выхода Windows XP часть оконных классов - так называемые базовые классы окон - кнопки, статические тексты (static text), поля ввода (editbox), скроллбары, списки и комбобоксы - хранилась в основной библиотеке (версия 5.80), отвечающей за элементы пользовательского интерфейса - user.exe. А вот в Windows XP новую версию библиотеки этих классов (версия 6.0) поместили в библиотеку comctl32.dll. Таким образом обеспечена обратная совместимость со старыми программами. Но чтобы сообщить программе, какую из двух библиотек следует использовать, и нужен манифест.

Чтобы было понятно, как ресурсы связываются с основной программой, нужно открыть файл makeit.bat (строки мы пронумеровали для наглядности):

@echo off

if not exist rsrc.rc goto over1

\masm32\bin\rc /v rsrc.rc

\masm32\bin\cvtres /machine:ix86 rsrc.res

:over1

if exist "template.obj" del "basicdlg.obj"

if exist "template.exe" del "basicdlg.exe"

\masm32\bin\ml /c /coff "basicdlg.asm"

if errorlevel 1 goto errasm

if not exist rsrc.obj goto nores

\masm32\bin\Link /SUBSYSTEM:WINDOWS "basicdlg.obj" rsrc.res

if errorlevel 1 goto errlink

dir "basicdlg.*"

goto TheEnd

:nores

\masm32\bin\Link /SUBSYSTEM:WINDOWS "basicdlg.obj"

if errorlevel 1 goto errlink

dir "basicdlg.*"

goto TheEnd

:errlink

echo _

echo Link error

goto TheEnd

:errasm

echo _

echo Assembly Error

goto TheEnd

:TheEnd

pause

Обратим внимание на выделенные строки 3,4, 8 и 11.

Строка 3. \masm32\bin\rc /v rsrc.rc – это компиляция ресурсного файла из исходного представления в формат Windows Resource.

Строка 4. \masm32\bin\cvtres /machine:ix86 rsrc.res – это конвертация ресурсного файла в объектный формат (результат – файл rsrc.res), чтобы потом этот формат понял компоновщик Link.

Строка 8. \masm32\bin\ml /c /coff "basicdlg.asm" – это компиляция исходного текста программы в объектный формат (результат – файл basicdlg.obj).

И, наконец, строка 11. \masm32\bin\Link /SUBSYSTEM:WINDOWS "basicdlg.obj" rsrc.res – это компоновка исполняемого ЕХЕ-модуля из объектных файлов basicdlg.obj и rsrc.res. Результатом будет файл basicdlg.exe.

Программа, которая будет загружаться из этого ехе-файла, будет строить GUI, используя всю переданную ей ресурсную информацию и производя правильные вызовы процедур и функций WinAPI, которые и реализуют в данной ситуации сервис операционной системы.

Остается разобраться, как организуются упомянутые выше «правильные вызовы процедур и функций WinAPI».

В принципе, ничто не мешает, изучив по MSDN (Microsoft Developer’s Network – справочный ресурс по средствам программирования под Windows) всё многообразие функций WinApi, прописывать их вызовы с «нулевого уровня вложенности», т.е. прямо из asm-файла исходного текста программы. Это путь возможный, но крайне громоздкий и трудоемкий. И при этом мы игнорируем огромный труд, который проделан создателями МАСМ для облегчения этих действий и придания им прозрачности и понятности. Понятно, что отбрасывать подобное богатство просто нелепо.

Поэтому мы на простом примере посмотрим, как практически программа «дотягивается» до функций WinApi через цепочки промежуточных вызовов макросов и процедур. Для этой работы нам понадобится, кроме обычного Windows Проводника еще и доступ к MSDN. Если вам доступен интернет, то мы рекомендовали бы ресурс http://msdn.microsoft.com/ru-ru/library/ms123401, дающий доступ к русскоязычной версии MSDN.

Рассмотрим наипростейший пример в папке \MASM32\examples\dialogs\simple. Откроем в Notepad++ файл simple.asm:

  1. ; ««««««««««««««««««««««««««««««««

.486 ; create 32 bit code

.model flat, stdcall ; 32 bit memory model

option casemap :none ; case sensitive

include \masm32\include\dialogs.inc

include simple.inc

dlgproc PROTO :DWORD,:DWORD,:DWORD,:DWORD

.code

; ««««««««««««««««««««««««««««««««

start:

mov hInstance, FUNC(GetModuleHandle,NULL)

call main

invoke ExitProcess, eax

; ««««««««««««««««««««««««««««««««

main proc

Dialog "Simple Dialog","MS Sans Serif",10, \ ; caption,font,pointsize

WS_OVERLAPPED or WS_SYSMENU or DS_CENTER, \ ; style

2, \ ; control count

50,50,150,80, \ ; x y co-ordinates

1024 ; memory buffer size

DlgButton "&OK",WS_TABSTOP,48,40,50,15,IDCANCEL

DlgStatic "Simple Dialog Written In MASM32",SS_CENTER,2,20,140,9,100

CallModalDialog hInstance,0,dlgproc,NULL

ret

main endp

; ««««««««««««««««««««««««««««««««

dlgproc proc hWin:DWORD,uMsg:DWORD,wParam:DWORD,lParam:DWORD

.if uMsg == WM_INITDIALOG

invoke SendMessage,hWin,WM_SETICON,1,FUNC(LoadIcon,NULL,IDI_ASTERISK)

.elseif uMsg == WM_COMMAND

.if wParam == IDCANCEL

jmp quit_dialog

.endif

.elseif uMsg == WM_CLOSE

quit_dialog:

invoke EndDialog,hWin,0

.endif

xor eax, eax

ret

dlgproc endp

; ««««««««««««««««««««««««««««««««

end start

В тексте этой программы мы выделили полужирным имена вызываемых макросов и процедур, условно говоря, «нулевого» уровня, т.е. находящиеся в этом тексте.

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

Таблица 5.1 – Таблица вызовов для программы simple.asm

Тип

Имя пр/макро

Вызвано

Вызвано

Описано в

1

2

3

4

5

p

GetModuleHandle

MSDN

p

ExitProcess

MSDN

m

Dialog

 

 

dialogs.inc

p

 

GlobalAlloc

 

 MSDN

m

 

ustring

 

dialogs.inc

p

 

 

MultiByteToWideChar

 MSDN

m

DlgButton

 

 

dialogs.inc

m

 

ustring – см.выше

 

m

DlgStatic

 

 

dialogs.inc

Продолжение таблицы 5.1

1

2

3

4

5

m

 

ustring – см.выше

 

m

CallModalDialog

 

 

dialogs.inc

p

 

DialogBoxIndirectParam

 

 MSDN

p

 

GlobalFree

 

 MSDN

p

SendMessage

MSDN

p

LoadIcon

MSDN

p

EndDialog

MSDN

Колонка «Тип» содержит «p» для процедур, «m» для макросов. Колонки 3 и 4 (их могло бы быть и больше, если бы цепочки вызовов были длиннее) содержат имена вызывемых макросов или процедур, последняя колонка указывает, где описан соответствующий макрос или процедура. Если процедура описана в MSDN, то она из WinAPI, дальше вызовы не прослеживаются.

Поясним, как составлялась таблица, на примере вызова макроса Dialog и далее того, что из него вызывается (отмеченная часть таблицы 5.1).

Итак, в тексте программы находим вызов

Dialog "Simple Dialog","MS Sans Serif",10, \ ; caption,font,pointsize

WS_OVERLAPPED or WS_SYSMENU or DS_CENTER, \ ; style

2, \ ; control count

50,50,150,80, \ ; x y co-ordinates

1024 ; memory buffer size

Чтобы найти его определение, открываем папку MASM32 и задаем поиск с параметрами:

Рисунок 5.1 – Поиск файла с определением макроса Dialog.

Результат поиска покажет, что этот макрос определен в файле \MASM32\include\dialogs.inc.

Открываем этот файл и читаем определение макроса:

Dialog MACRO quoted_text_title,quoted_font,fsize,dstyle,ctlcnt,tx,ty,wd,ht,bsize

push esi

push edi

invoke GlobalAlloc,GMEM_FIXED or GMEM_ZEROINIT,bsize

mov esi, eax

mov edi, esi

mov DWORD PTR [edi+0], DS_SETFONT or dstyle

mov WORD PTR [edi+8], ctlcnt

mov WORD PTR [edi+10], tx

mov WORD PTR [edi+12], ty

mov WORD PTR [edi+14], wd

mov WORD PTR [edi+16], ht

add edi, 22

ustring quoted_text_title

mov WORD PTR [edi], fsize

add edi, 2

ustring quoted_font

ENDM

Видим, что в нем макросом invoke, изученным раньше, вызывается процедура GlobalAlloc и дважды вызывается макрос ustring.

Сначала обращаемся к MSDN и поиском в ней находим подтверждение предположению, что это функция из WinAPI.

Поиском в папке MASM32 находим, что макрос ustring определен в том же файле dialogs.inc. Открываем и читаем определение этого макроса:

ustring MACRO quoted_text

LOCAL asc_txt

.data

asc_txt db quoted_text,0

.code

invoke MultiByteToWideChar,CP_ACP,MB_PRECOMPOSED,

ADDR asc_txt,-1,edi,LENGTHOF asc_txt

add edi, LENGTHOF asc_txt*2

ENDM

Видим, что из него вызывается только процедура MultiByteToWideChar, описание которой находим в MSDN. Таким образом, мы проследили цепочки всех вызовов по макросу Dialog до уровня WinAPI (процедур, описанных в MSDN). Как результат этого прослеживания можно сделать вывод, что в макросе Dialog, помимо действий, выраженных командами ассемблера, содержатся, в конечном итоге, вызовы функций GlobalAlloc() и MultiByteToWideChar().

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