Добавил:
ivanov666
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз:
Предмет:
Файл:Разработка приложений на языке ассемблер в среде MS MASM. Учебно-методическое пособие по дисциплинам «Ассемблер» и «Операционные системы и системное п
.pdf
Первый блок программы (строки 1-3) содержит «шапку» программы
и включает строки комментария, поясняющие что это за программа, кто ее
автор и, возможно, другую информацию. При выполнении всех лабораторных работ шапка программы должна присутствовать обязательно!
Второй блок (строки 4-6) служат для определения общих требований
к ассемблеру при построении объектного кода. В данном случае здесь указаны директивы, с помощью которых определяется тип процессора и устанавливаются характеристики используемой модели памяти программы
(плоская модель, соглашение о вызовах).
Третий блок (строка 7) содержит директиву определения стека программы (.stack), в которой указывается его размер в байтах (100h соот-
ветствует 256 байтам).
В четвёртом блоке (строки 8-13) подключаются необходимые системные модули и библиотеки для организации вывода результатов на экран. В
них содержатся системные функции, к которым будет производиться обращение в процессе выполнения программы. Обратите внимание, что необходимо правильно указать путь к расположению указанных файлов в соответствии с местом установки пакета MASM.
Пятый блок (строки 14-16) описывает сегмент данных программы.
Сегмент помечается директивой .data, после которой следуют дирек-
тивы определения переменных. В данном случае определено две переменные строкового типа с именами tit и hello.
И, наконец, шестой блок (строки 17-26) содержит код программы.
Начало кода отмечается директивой .code и завершается директивой
end. В качестве параметра директивы end (строка 26) указывается метка
(здесь - main), с которой будет начинаться выполнение данной программы
(строка 18). Программа содержит 7 команд ассемблера, записанных в стро-
ках 19-25. Команда PUSH служит для помещения значений в стек. Команда
CALL обеспечивает вызов системной функции Windows с указанным именем.
Строки 19-22 предназначены для формирования параметров вызова
системной функции MessageBox, предназначенной для вывода текстовой
информации на экран в виде диалогового окна. В стек поочерёдно записываются параметры функции: тип диалогового окна (строка 19); адрес переменной, в которой хранится заголовок окна, в данном случае tit (строка
20); адрес переменной, в которой хранится выводимый текст, в данном случае hello (строка 21); дескриптор окна-владельца сообщения (строка 22).
В регистр DX заносится адрес переменной hello в сегменте данных
(строка 13), а в регистр AH - номер функции вывода (строка 14). В строке
23 производится вызов функции вывода диалогового окна. Отметим, что
11

для правильной обработки текстовой строки, предназначенной для вывода,
команды
она должна завершаться символом с кодом 0 (см. строку 15).
Строки 24-25 всегда записывают в конце любой программы, так как
они служат для завершения ее выполнения. В строке 24 в стек помещается
код выхода из программы, а в строке 25 вызывается функция, завершающая
работу программы. Последние две операции можно выполнить, используя
макрос (invoke ExitProcess,0).
2.2 Этапы разработки программ на ассемблере
Создание программы на языке ассемблер начинается с написания текста программы. Файл, который содержит программу на языке ассемблер,
называют исходным файлом или исходным кодом. В таком виде программа
не может быть выполнена. Необходимо преобразовать исходный код в его
представление на машинном языке (машинный код). Такое преобразование
осуществляет специальная программа, которую принято называть «ассемблер». Поэтому процесс преобразования называют «ассемблирование».
Программа-ассемблер берет программу, написанную на языке ассемблер, и
превращает ее в машинный код. В результате формируется файл, который
называют объектным файлом. Данные в нем называются объектным ко-
дом.
Помимо преобразования исходного кода в объектный ассемблер создает несколько других выходных файлов. Один из них - ассемблерный ли-
стинг. Листинг содержит исходный код программы вместе с комментариями, сообщения о действиях ассемблера, а также объектный код, сформированный ассемблером. На рисунке 2.2 приведен фрагмент листинга программы hello, описанной в п. 2.1.
Microsoft (R) Macro Assembler Version 6.14.8444 07/04/21 11:32:11
hello.asm Page 1 – 1
00000000 .code ;Начало сегмента кода
00000000 main: ;Метка входа в программу
00000000 6A 00 push 0
00000002 68 00000000 R push offset tit ;Заголовок окна
00000007 68 0000000C R push offset hello ;Текст для вывода
0000000C 6A 00 push 0
0000000E E8 00000000 E call MessageBox ;Вызов функции вывода на экран
00000013 6A 00 push 0
00000015 E8 00000000 E call ExitProcess ;Завершаем работу программы
Адрес
Объектный
код
Исходный код
Рисунок 2.2 – Фрагмент листинга программы hello
В правой части листинга размещаются команды, записанные программистом (исходный код). В левой части – информация, сгенерированная
12

ассемблером. В первой колонке содержатся адреса команд, вырабатываемые ассемблером (00000000-00000015). Вторая колонка содержит объектный код команд на машинном языке. Команды микропроцессора Intel могут
занимать от 1 до 15 байт, поэтому это поле будет изменяться в размере.
Следует отметить, что на этапе ассемблирования невозможно точно сформировать значения некоторых адресных операндов. Например, адреса переменных, описанных в сегменте данных программы, а также адреса вызываемых системных функций. В этом случае вместо истинных адресов ячеек
памяти для переменных в объектном коде указывают так называемые эф-
фективные адреса. Эффективный адрес равен простому смещению переменной относительно начала сегмента: адрес первой переменной всегда
принимается равным нулю, адрес следующей переменной определяется по
количеству байт, занимаемых первой и т.д. Такие адреса в объектном коде
листинга помечаются символом «R». Адреса вызываемых внешних функций остаются нулевыми и помечаются символом «E». Адреса, помеченные
символами R и E, в дальнейшем на этапе редактирования связей и выполнения (загрузки в память) будут заменены на реальные адреса оперативной
памяти, которая будет выделена для соответствующих объектов. В остальном листинг ассемблера дает верные машинные коды, которые и будут в
дальнейшем исполняться. Листинг содержит также таблицу символических
имен, содержащую перечень всех идентификаторов, включая метки и
имена переменных, их типы и адреса.
Если в исходном коде программы программист допустил синтакси-
ческие ошибки, то в листинге (а также на экране консоли) будут сформированы соответствующие сообщения, с указанием ошибочной строки исходного кода.
Объектный код не может быть выполнен компьютером непосредственно. Для получения из объектного кода исполняемого машинного кода,
он должен быть изменен в части адресов вызова функций из подключаемых
внешних модулей. Эту работу выполняет программа, которую называют
редактором связей. Поэтому шаг преобразования объектных кодов в машинные принято называть редактированием связей или линковкой. Результатом этого шага является создание загрузочного (исполнимого) файла, содержащего загрузочный код программы. Редактор связей может объединять
несколько объектных файлов в единый загрузочный файл.
Важным средством, используемым при разработке ассемблерных
программ, является программа-отладчик, с помощью которой можно выполнить программу в пошаговом режиме и проследить за тем, как при этом
изменяются значения регистров процессора и содержимое ячеек памяти,
где хранятся переменные. Важно: отладчик позволяет увидеть реальные адреса используемых переменных и вызываемых внешних функций (в отли-
13

чие от адресов, представленных в объектном коде)! Отладчик обычно ис-
Этап
Что делать
Как (с помощью)
Что будет получено
кода
программы
Far)*
стинга (
имя.lst
)
нуться к этапу 1
граммы
ния
этапу 1
шаговом режиме
пользуют для обнаружения ошибок времени выполнения программы,
наблюдая в пошаговом режиме насколько получаемые значения переменных и регистров соответствуют воображаемой программистом логике работы программы.
Выполнение ассемблирования, линковки и отладки осуществляется с
помощью специальных программ. В данной работе будут использованы
программы из комплекта Microsoft Macro Assembler (MASM32)
(masm32.com), включающие ассемблер ml.exe, редактор связей PoLink.exe.
В качестве отладчика будет использован отладчик ollydbg.exe.
В таблице 2.1 представлены основные этапы создания программ на
языке ассемблер с использованием средств MASM и отладчика OllyDebug.
Таблица 2.1 - Этапы и средства разработки программ
1 Создание и редакти-
рование исходного
Текстовый редактор
(Notepad++, Word,
2 Ассемблирование Ассемблер ml.exe:
ml.exe /c /coff /Sn
/Fl"имя.lst" "имя.asm"
3 Выявление синтакси-
ческих ошибок. Если
обнаружены, вер-
4 Линковка (редакти-
рование связей)
5 Выполнение про-
6 Использование от-
ладчика (при необхо-
Анализ сообщений ассемблера и файла листинга
Редактор связей
PoLink.exe:
PoLink
/SUBSYSTEM:WINDOWS
"имя.obj"
Запуск файла имя.exe Результаты и сообще-
Отладчик ollydbg.exe:
ollydbg имя.exe
димости). Для корректировки программы вернуться к
Исходный файл
(имя.asm)
Объектный файл
(имя.obj) и файл ли-
Исполняемый файл
имя.exe
Содержимое регистров процессора и
ячеек памяти (дамп),
значения переменных
при выполнении в по-
*) Примечание. Для возможности прочтения символов кириллицы в отладчике и листинге рекомендуется при создании оконной Windows-программы
сохранять исходный текст в кодировке Windows-1251, при создании консольной
программы используется кодировка ASCII.
14

2.3 Рабочее задание и порядок выполнения работы
2.3.1 Установка программного обеспечения MASM
Скачайте установочный дистрибутив MASM (masm32.com) и установите на свой компьютер, запустив файл install.exe. Для установки рекомендуется выбрать диск C:. В результате необходимые для разработки программ файлы ml.exe и polink.exe будут размещены в папке С:\masm32\bin.
2.3.2 Создание EXE файла
1. Создайте личную папку для размещения разрабатываемых программ. С использованием одного из доступных текстовых редакторов (рекомендуется Notepad++) создайте файл с именем hello.asm и введите
текст программы, представленный в п. 1.5. В шапке программы, а также в
текстовой строке (переменная Hello) укажите свое имя и фамилию.
Cохраняйте исходный текст программы в формате обычного текстового
файла в кодировке Windows 1251.
2. Выполните ассемблирование программы, набрав в командной
строке:
ml /c /coff /Sn /Fl"hello.lst" "hello.asm"
Результатами ассемблирования будут объектный файл hello.obj и
файл листинга hello.lst
Обратите внимание: здесь и далее для корректного использования указанных в команде файлов (включая ml.exe) необходимо точно указать путь к ним (например,
c:\masm32\bin\ml), либо добавить к системной переменной PATH имена соответствующих
папок. В частности, полезно (но не необходимо) прописать в системе путь к файлам ассемблера. Для этого на рабочем столе нужно сделать правый клик на "Компьютер" > Свойства >
Дополнительные параметры системы > закладка "Дополнительно" > Переменные среды.
Здесь в списке системных переменных нужно изменить значение переменной "Path", дописав
в конце строки путь к папке, содержащей ассемблер и редактор связей, например,
С:\MASM32\bin. Это позволит не писать полный путь к компилятору и редактору связей при
обращении к ним.
3. Просмотрите файл листинга hello.lst. Если обнаружены сообщения об ошибках, внесите изменения в исходный файл hello.asm и
повторите ассемблирование.
4. Выполните редактирование связей программы, набрав в командной
строке:
polink /SUBSYSTEM:WINDOWS "hello.obj"
В результате должен быть создан исполнимый файл hello.exe.
5. Выполните полученную программу, для чего введите в командной
строке:
hello.exe или просто: hello
и нажмите Enter
На экране должна появиться фраза «Здравствуйте...».
15

2.3.3 Использование отладчика
1. Запустите отладчик, указав в командной строке сначала имя программы-отладчика, а затем имя загрузочного модуля создаваемой программы hello.exe:
ollydbg hello.exe
Можно поступить иначе: вначале запустить отладчик, а затем с помо-
щью меню File->Open выбрать исполняемый файл.
2. Ознакомьтесь со структурой и содержимым окна отладчика. Интерфейс OllyDbg (см. рисунок 2.3) состоит из следующих компонентов:
главное меню, панель с кнопками для быстрого доступа, рабочая область и
строка состояния. Рабочая область подразделяется на 4 части.
Сегмент
кода
Сегмент
данных
Регистры
и флаги
Сегмент
стека
Рисунок 2.3 - Окно отладчика OllyDbg
В левой верхней четверти экрана располагается область сегмента
кода. Первая колонка содержит адрес команды, вторая – машинный исполняемый код команды, третья – дизассемблированный текст программы,
четвёртая – пояснения от отладчика. Обратите внимание, что в тексте программы вместо имен переменных фигурируют адресные выражения, указывающие на размещение соответствующей переменной в памяти. Операторы BYTE PTR, WORD PTR, DWORD PTR определяют тип (длину) пере-
менной: соответственно байт, слово (2 байта) и двойное слово (4 байта).
16

В правой верхней части отображаются значения регистров процес-
сора (EAX, ECX, EDX, EBX, ESP, EBP, ESI, EDI, EIP) и флаги (C, P, A, Z, S,
O).
В левой нижней части отображается содержимое (дамп) сегмента
данных отлаживаемой программы: первая колонка – адрес первой отобра-
жаемой в строке ячейки памяти, вторая – представление содержимого ячеек
памяти в шестнадцатеричном формате (по 16 байт в строке), третья – представление данных в кодировке ASCII.
Правую нижнюю часть занимает область сегмента cтека: первая
колонка – адрес ячейки стека, вторая – 4-х байтовое значение содержимого
ячейки в шестнадцатеричном виде, третья – значение содержимого в кодировке ASCII, четвёртая – пояснения от отладчика.
3. Нажимая на клавишу F8, произведите пошаговое выполнение про-
граммы. После каждого шага можно наблюдать изменение регистров процессора, значений переменных и содержимого стека.
4. Результат выполнения программы можно просмотреть, нажав кла-
виши Ctrl+F2. После этого необходимо будет заново открыть файл с программой или нажать ◄◄. В любой момент можно прервать выполнение
программы, нажав клавишу F12. Если пошаговый режим не нужен, программу можно выполнить целиком, нажав на кнопку ►.
2.3.4 Представление данных в ассемблере
1. Создайте файл с именем data.asm и введите текст программы,
представленный ниже:
;Лабораторная работа №1
;Выполнил ст. гр. УВА-313 Панферов В.Д.
;Программа 2 (DATA.ASM) Вариант №1
;============================================================
.486
.model flat, stdcall ;Устанавливается тип используемой модели памяти
option casemap: none
;============================================================
.stack 100h ;Определяется сегмент стека размером 256 байт
;============================================================
;Подключение необходимых модулей
include c:\masm32\include\windows.inc
include c:\masm32\include\user32.inc
include c:\masm32\include\kernel32.inc
includelib c:\masm32\lib\user32.lib
includelib c:\masm32\lib\kernel32.lib
;============================================================
.data ;Начало сегмента данных
A1 db 27 ;Определение однобайтовой переменной
A2 dw 0AE5h ;Определение двухбайтовой переменной (слова)
A3 dd 123456h ;Определение двойного слова (4 байта)
A4 db -2 ;Определение однобайтового числа со знаком
17

A5 dd A4 ;Определение четырехбайтового указателя на переменную
;============================================================
.code ;Начало сегмента кода
main: ;Метка, обозначающая точку входа в программу
mov bl, A1 ;Поместить в регистр BL значение переменной A1
mov bh, A4-2 ;Поместить в регистр BH байт памяти с адресом A4-2
mov ecx, offset A2 ;Поместить в регистр ECX адрес переменной A2
mov ax, A2 ;Поместить в регистр AX значение переменной A2
mov si, A2+1 ;Поместить в регистр SI слово памяти по адресу A2+1
invoke ExitProcess,0 ;Вызов функции завершения программы
end main ;Конец программы
2. Ориентируясь на приведенные в тексте программы комментарии,
проанализируйте структуру программы, изучите содержимое сегмента данных и сегмента кода. Обратите внимание на соответствие размера регистров типам используемых переменных. Пользуясь лекционными материалами или другими источниками, ответьте на следующие вопросы:
- какие переменные объявлены в программе, какого они типа, какими
значениями инициализированы?
- как работает команда mov?
- какие регистры используются в качестве операндов команд, какого
они типа?
- что означают адресные выражения offset A2, A4-2 и A2+1?
3. Создайте исполнимый файл data.exe и запустите программу в
отладчике.
4. Изучите информацию отладчика о программе data, воспользовавшись пояснениями, представленными на рисунках 2.4 и 2.5.
Рисунок 2.4 - Отладчик. Содержимое сегмента данных
18

менная
(байт)
адрес
A1
байт
1 0
A2
...
A1 A2 A5
1
Bh
402000
402001
...
Рисунок 2.5 - Отладчик. Содержимое сегмента кода
5. Используя исходный текст программы data, а также информацию,
полученную из отладчика и листинга, заполните представленные ниже таб-
лицы 2.2, 2.3 и 2.4.
Таблица 2.2 - Содержимое сегмента данных программы data
Пере-
Тип Длина
Эффективный
Эффективный адрес переменной определяется как простое смещение
первой ячейки переменной относительно начала сегмента данных.
Таблица 2.3 - Дамп сегмента данных программы data
19

стингу)
дампу)
(байт)
регистров
…
…
Таблица 2.4 - Результаты пошагового выполнения программы data
№ Команда Код ма-
шинной
команды
(по ли-
Mov bl,A1
1
Код ма-
шинной
команды
(по
Длина
машин-
ной ко-
манды
Значения
EAX EBX ECX ESI EIP
Код и длина машинной команды определяются по листингу и дампу
программы (две шестнадцатеричные цифры составляют один байт). Значения регистров фиксируются после выполнения соответствующей команды
в отладчике. Выделяйте ячейки со значениями регистров, которые изменились после выполнения команды!
2.4 Использование командных файлов
Для удобного запуска команд, применяемых для ассемблирования,
линковки, выполнения и отладки программ рекомендуется воспользоваться
командными файлами Windows.
1. В личной папке создайте файл с именем runasm.bat и введите
(сохраните) в него следующий текст:
rem Командный файл для создания и выполнения программы
rem Программист ... (укажите своё имя)
@echo off
if exist "hello.obj" del "hello.obj"
if exist "hello.exe" del "hello.exe"
rem Ассемблирование
c:\masm32\bin\ml /c /coff /Sn /Fl"hello.lst" "hello.asm"
if errorlevel 1 goto errasm
rem Редактирование связей
c:\masm32\bin\PoLink /SUBSYSTEM:WINDOWS "hello1.obj"
if errorlevel 1 goto errlink
dir "hello.*"
goto TheEnd
:errlink
echo _
echo Link error
goto TheEnd
:errasm
echo _
echo Assembly Error
20
Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]
