Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Разработка приложений на языке ассемблер в среде MS MASM. Учебно-методическое пособие по дисциплинам «Ассемблер» и «Операционные системы и системное п

.pdf
Скачиваний:
1
Добавлен:
08.09.2026
Размер:
2 Мб
Скачать
Первый блок программы (строки 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
Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]