37727

Программирование на ассемблере MASM32. Изучение среды разработки RADasm и отладчика OllyDbg

Лабораторная работа

Информатика, кибернетика и программирование

Они необходимы программе для обработки и хранения в памяти команд и данных а также получения информации о собственном текущем состоянии и состоянии процессора.1: пространство адресуемой памяти до 2х в 32й степени байт 4 Гбайт для Pentium II и выше до 2х в 36 степени байт 64 Гбайт; регистры для хранения данных общего назначения; сегментные регистры; регистры состояния и управления; регистры устройства вычислений с плавающей запятой сопроцессора; набор регистров целочисленного MMXрасширения отображенных на регистры...

Русский

2013-09-25

584.5 KB

300 чел.

Федеральное агентство по образованию

Государственное образовательное учреждение

высшего профессионального образования

«МАТИ» – Российский государственный

технологический университет им. К.Э.Циолковского

Кафедра «Технология производства приборов и информационных систем управления летательных аппаратов»

Программирование на ассемблере MASM32. Изучение среды разработки RADasm и отладчика OllyDbg.

Методические указания к лабораторной работе

по дисциплине  «Архитектура ЭВМ и систем»,

для специальности 230102.65 «Автоматизированные системы обработки информации и управления»

Автор: Пахомов М.М.

Москва 2012


Содержание

Введение

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

2. Теоретические основы

3. Используемое оборудование

4. Порядок работы с интегрированной средой разработки

5. Порядок выполнения работы

Литература

Введение

Настоящее методическое пособие является указанием для выполнения первой лабораторной работы по дисциплине «Архитектура ЭВМ и систем».

Данный курс лабораторных работ направлен на изучения основ программирования на 32-х разрядном ассемблере с использованием транслятора MASM32. Основная цель лабораторного курса - дать учащимся теоретические знания и практические навыки низкоуровневого программирования. Выполнив курс лабораторных работ, студент не только освоит основы программирования на ассемблере, но также получит более глубокое и детальное представление о работе компьютера.

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

1. Научиться работать в интегрированной среде разработки программ на языке ассемблера, состоящей из специализированного пакета программирования MASM32, среды RADAsm и отладчика OllyDbg.

2. Изучить общую структуру программы на языке ассемблера.

3. Изучить программную модель процессора IA-32.

2. Теоретические основы.

Любой программе на ассемблере для ее исполнения выделяется определенный набор ресурсов компьютера. По большей части это ресурсы, предоставляемые процессором. Они необходимы программе для обработки и хранения в памяти команд и данных, а также получения информации о собственном текущем состоянии и состоянии процессора.

Программную модель процессора в архитектуре IA-32  составляет следующий набор ресурсов (рис. 2.1):

- пространство адресуемой памяти до 2-х в 32-й степени байт (4 Гбайт), для Pentium II и выше — до 2-х в 36 степени байт (64 Гбайт);

- регистры для хранения данных общего назначения;

- сегментные регистры;

- регистры состояния и управления;

- регистры устройства вычислений с плавающей запятой (сопроцессора);

- набор регистров целочисленного MMX-расширения, отображенных на регистры сопроцессора (впервые появились в архитектуре процессора Pentium MMX);

- набор регистров MMX-расширения с плавающей точкой (впервые появились в архитектуре процессора Pentium III);

- программный стек — специальная информационная структура, для работы с которой предусмотрены специальные машинные команды. Кроме того, к ресурсам, поддерживаемым архитектурой IA-32, необходимо отнести порты ввода-вывода, счетчики мониторинга производительности. Программные модели более ранних процессоров (i486, первые Pentium до Pentium MMX включительно) отличаются меньшим размером адресуемого пространства оперативной памяти (максимально 2 в 32-й степени адресов, так как разрядность их шины адреса составляет 32 бита) и отсутствием некоторых групп регистров. На рис. 2.1 для каждой группы регистров в

Рис. 2.1. Программная модель процессора семейства IA-32.

скобках показано, начиная с какой модели она появилась в программной модели процессоров INTEL. Если такого обозначения нет, то это означает, что данная группа регистров присутствовала в процессорах i386 и i486. Еще более ранние процессоры i8086/88, тоже полностью представлены на схеме, но составляют лишь небольшую ее часть. В программную модель этих процессоров входят 8- и 16-разрядные регистры общего назначения, сегментные регистры, регистры FLAGS, IP и адресное пространство памяти размером до 1 Мбайт.

Большинство регистров имеют определенное функциональное назначение. С точки зрения программиста, их можно разделить на две большие группы.

Первую группу образуют пользовательские регистры, к которым относятся:

- регистры общего назначения EAX/AX/AH/AL*, EBX/BX/BH/BL, EDX/DX/DH/DL, ECX/CX/CH/CL, EBP/BP, ESI/SI, EDI/DI, ESP/SP предназначены для хранения данных и адресов, программист может их использовать (с определенными ограничениями) для реализации своих алгоритмов;

* В обозначениях многих регистров программной модели присутствует наклонная разделительная черта. Это не разные регистры, а части одного большого 32-разрядного регистра. Наклонная черта означает, что эти регистры можно использовать в программе как отдельные объекты. Так сделано для обеспечения работоспособности программ, написанных для прежних 16-разрядных моделей процессоров фирмы Intel, начиная с i8086. Процессоры i486 и Pentium включают в себя в основном 32-разрядные регистры. Их количество, за исключением сегментных регистров, такое же как и у i8086, но емкость больше, что и отражено в обозначениях, — они имеют приставку E (Extended).

- сегментные регистры CS, DS, SS, ES, FS, GS служат для хранения значений, интерпретация которых зависит от режима работы процессора. В реальном режиме сегментные регистры содержат адрес параграфа начала сегмента в памяти. В защищенном режиме сегментные регистры хранят индекс входа в одну из системных таблиц дескрипторов — GDT или LDT;

- регистры сопроцессора ST(0), ST(1), ST(2), ST(3), ST(4), ST(5), ST(6), ST(7) предназначены для написания программ, оперирующих данными с плавающей запятой;

- целочисленные регистры целочисленного MMX-расширения MMX0, MMX1, MMX2, MMX3, MMX4, MMX5, MMX6, MMX7;

- регистры XMM-расширения с плавающей запятой XMM0, XMM1, XMM2, XMM3, XMM4, XMM5, XMM6, XMM7;

- регистры состояния и управления (регистр флагов EFLAGS/FLAGS и регистр указателя команды EIP/IP) содержат информацию о состоянии процессора, исполняемой программы и позволяют изменить это состояние.

Во вторую группу входят системные регистры, то есть предназначенные для обеспечения различных режимов работы, сервисных функций, а также регистры, специфичные для определенной модели процессора. К системным регистрам, поддерживаемым IA-32, относятся:

- управляющие регистры CR0–CR4 — определяют режим работы процессора и характеристики текущей исполняемой задачи;

- регистры управления памятью GDTR, IDTR, LDTR и TR используются в защищенном режиме работы процессора для локализации управляющих структур этого режима;

- отладочные регистры DR0–DR7 предназначены для контроля и управления различными аспектами отладки;

- регистры типов областей памяти MTRR используются для аппаратного управления кэшированием в целях назначения соответствующих свойств областям памяти;

- машинно-зависимые регистры MSR задействуются для управления процессором, контроля за его производительностью, получения информации об ошибках.

Регистры общего назначения привлекаются для хранения операндов команд целочисленного устройства, а также адресов и компонентов адреса.

На хранение операндов не накладываются особые ограничения, но в определенных условиях некоторые из регистров имеют жесткое функциональное назначение, закрепленное на уровне логики работы машинных команд. В этой связи среди всех регистров общего назначения особо следует выделить регистр ESP. В нем хранится указатель на вершину стека программы, и хранить здесь какие-либо операнды неразумно и небезопасно.

Перечислим регистры, относящиеся к группе регистров общего назначения и физически находящиеся в процессоре внутри арифметико-логического устройства ( регистры АЛУ):

- регистр-аккумулятор (accumulator register) EAX/AX/AH/AL применяется для хранения промежуточных данных, в некоторых командах его использование обязательно;

- базовый регистр (base register) EBX/BX/BH/BL задуман как место хранения базового адреса некоторого объекта в памяти;

- регистр-счетчик (count register) ECX/CX/CH/CL применяется в командах, производящих некоторые многократные действия;

- регистр данных (data register) EDX/DX/DH/DL, так же как и регистр EAX/AX/AH/AL, хранит промежуточные данные (в некоторых командах его явное использование обязательно, в других его участие подразумевается неявно).

Следующие два регистра предназначены для поддержки так называемых цепочечных операций, то есть операций, производящих последовательную обработку цепочек элементов, каждый из которых может иметь длину 32, 16 или 8 бит:

- регистр индекса источника (source index register) ESI/SI в цепочечных операциях содержит текущий адрес элемента в цепочке-источнике;

- регистр индекса приемника (destination index register) EDI/DI в цепочечных операциях содержит текущий адрес в цепочке-приемнике.

Для работы со стеком в системе команд процессора есть специальные команды, а в программной модели процессора для этого существуют специальные регистры:

- регистр указателя стека (stack pointer register) ESP/SP содержит указатель на вершину стека в текущем сегменте стека;

- регистр указателя базы кадра стека (base pointer register) EBP/BP предназначен для организации произвольного доступа к данным внутри стека.

Сегментные регистры необходимы для аппаратной поддержки сегментной организации программы. Это означает, что любая программа состоит как минимум из трех сегментов: кода, данных и стека. Логически машинные команды в архитектуре IA-32 построены так, что при выборке каждой команды для доступа к данным программы или к стеку неявно используется информация из вполне определенных сегментных регистров. В зависимости от режима работы процессора по их содержимому определяются адреса памяти, с которых начинаются соответствующие сегменты. В программной модели IA-32 имеется шесть сегментных регистров CS, SS, DS, ES, GS, FS, служащих для доступа к четырем типам сегментов.

Сегмент кода. Содержит команды программы. Для доступа к этому сегменту служит регистр сегмента кода (code segment register) CS. Он содержит значение, которое по-разному интерпретируется процессором, в зависимости от текущего режима работы. В реальном режиме — это адрес первого параграфа сегмента, в защищенном — индекс элемента в таблице дескрипторов (глобальной GDT или локальной LDT).

Сегмент данных. Хранит обрабатываемые программой данные. Для доступа к этому сегменту служит регистр сегмента данных (data segment register) DS, в который помещен адрес сегмента данных текущей программы.

Сегмент стека. Представляет собой область памяти, называемую стеком. Работу со стеком процессор организует по следующему принципу: последний записанный в эту область элемент выбирается первым. Доступ к области стека выполняется через регистр сегмента стека (stack segment register) SS, содержащий адрес сегмента стека.

Дополнительный сегмент данных. Неявно алгоритмы выполнения большинства машинных команд предполагают, что обрабатываемые ими данные расположены в сегменте данных, адрес которого находится в регистре сегмента данных DS. Если программе недостаточно одного сегмента данных, то она имеет возможность одновременно задействовать еще три дополнительных сегмента данных, адреса которых должны содержаться в регистрах дополнительного сегмента данных (extension data segment registers) ES, GS, FS. Среди них следует особо выделить регистр ES. Он используется для обеспечения цепочечных команд процессора, адресуя собой операнд-источник.

В процессор Intel включены регистры состояния и управления              (см. рис. 2.1), постоянно содержащие информацию о состоянии самого процессора и программы, команды которой он в данный момент обрабатывает:

- регистр указателя команды EIP/IP;

- регистр флагов EFLAGS/FLAGS.

С помощью этих регистров можно также ограниченным образом управлять состоянием процессора. Регистр указателя команд (instruction pointer register) EIP/IP имеет разрядность 32/16 бит и содержит смещение следующей подлежащей выполнению команды относительно начала сегмента кода. Этот регистр непосредственно недоступен программисту, то есть его нельзя указывать в качестве операнда команд. Но к нему возможен косвенный доступ, так загрузка и изменение его содержимого производятся в результате работы различных команд управления программным потоком, к которым относятся команды условных и безусловных переходов, вызова процедур и возврата из процедур. Возникновение прерываний также приводит к модификации содержимого регистра EIP/IP. Разрядность регистра флагов (FLAG REGISTER) EFLAGS/FLAGS равна 32/16 бит. Отдельные биты данного регистра имеют функциональное назначение и называются флагами. Младшая часть регистра EFLAGS/FLAGS полностью аналогична регистру FLAGS процессора i8086. На рис. 2.2 показано содержимое регистра EFLAGS.

Исходя из особенностей использования, флаги регистра EFLAGS/FLAGS делятся на три группы:

1. Флаги состояния — отражают особенности результата исполнения арифметических или логических операций и могут изменяться сознательно:

Флаг переноса (carry flag) CF — если равен 1, то арифметическая операция произвела перенос из старшего бита результата (или перенос инициирован командой сдвига) или в старший бит результата. Старшим является 7-й, 15-й или 31-й бит в зависимости от размерности операнда; если CF равен 0 — переноса не было. Этот флаг показывает условие переполнения для беззнаковой арифметики.

Флаг четности (parity flag) PF — если равен 1 — то 8 младших разрядов (этот флаг действителен только для 8 младших разрядов операнда любого размера) результата содержат четное число единиц; если равен 0 — среди 8 младших разрядов результата количество единиц нечетно.

Вспомогательный флаг переноса (auxiliary carry flag) AF — применяется только для команд, работающих с BCD-числами. Фиксирует

Рис.2.2. Содержимое регистра флагов.

факт заема из младшей тетрады результата: если равен 1 — в результате операции сложения был произведен перенос из разряда 3 в старший разряд или при вычитании был заем в разряд 3 младшей тетрады из значения в старшей тетраде; если равен 0 — переносов и заемов в третий разряд (из третьего разряда) младшей тетрады результата не было.

Флаг нуля (zero flag) ZF — когда равен 1 — результат нулевой; при равенстве 0 — результат ненулевой.

Флаг знака (sign flag) SF — отражает состояние старшего бита результата (биты 7, 15 или 31 для 8-, 16- или 32-разрядных операндов соответственно): если равен 1 — старший бит результата равен 1; если равен 0 — старший бит результата также 0.

Флаг переполнения (overflow flag) OF — используется для фиксации факта потери значащего бита при арифметических операциях со знаком: если равен 1 — в результате операции происходит перенос в старший знаковый бит результата или заем из старшего знакового бита результата (биты 7, 15 или 31 для 8-, 16- или 32-разрядных операндов соответственно); нулевое значение говорит об отсутствии переноса или заема.

2. Флаг направления DF (directory flag) — десятый бит регистра EFLAGS. Флаг DF используется цепочечными командами и определяет направление поэлементной обработки данных этими командами: DF = 0 — от начала цепочки к ее концу, то есть от младших адресов к старшим; DF = 1 — от конца цепочки к ее началу, то есть от старших адресов к младшим. Состояние флага DF можно изменить командами CLD (снять флаг DF) И STD (установить флаг DF).

3. Системные флаги и поле IOPL — управляют вводом-выводом, маскируемыми прерываниями, отладкой, переключением между задачами и режимом виртуального процессора 8086:

Флаг трассировки (trace flag) TF — предназначен для организации пошаговой работы процессора: если он равен 1 — процессор генерирует прерывание с номером 1 после выполнения каждой машинной команды (может использоваться при отладке программ); если равен 0 — обычная работа.

Флаг прерывания (interrupt enable flag) IF — предназначен для разрешения или запрещения (маскирования) аппаратных прерываний (прерываний по входу INTR): когда он равен 1 — аппаратные прерывания разрешены; при равенстве 0 — аппаратные прерывания запрещены.

Уровень привилегированности ввода-вывода (input/output privilege level) IOPL — используется в защищенном режиме работы процессора для контроля доступа к командам ввода-вывода в зависимости от назначенного задаче приоритета.

Флаг вложенности задачи (nested task) NT — используется в защищенном режиме работы процессора для запоминания того факта, что одна задача связана с другой по цепочке вызовов. Работа цепочки связанных задач организуется с помощью команд CALL, IRET, регистра задач TR и сегмента TSS.

Флаг возобновления (resume flag) RF — применяется при обработке прерываний от регистров отладки.

Флаг режима виртуального процессора 8086 (virtual 8086 mode) VM — признак текущего режима процессора: если он равен 1 — процессор функционирует в режиме виртуального процессора 8086; равенство 0 означает работу в реальном или защищенном режиме.

Флаг контроля выравнивания (alignment check) AC — предназначен для разрешения контроля выравнивания при обращениях к памяти. Используется совместно с битом AM в системном регистре CR0. Процессоры IA-32 (начиная с i80486) разрешают размещать команды и данные, начиная с любого адреса. Установка данных битов (при уровне привилегий CPL = 3), как правило, будет приводить к возникновению исключительной ситуации при попытках обращения к данным и командам по адресам, некратным 2 или 4.

Флаг виртуального прерывания (virtual interrupt flag) VIF (только Pentium) — при определенных условиях, одно из которых — работа процессора в V-режиме, является аналогом флага IF. Флаг VIF используется совместно с флагом VIP (при CR4.VME = 1).

Флаг отложенного виртуального прерывания (virtual interrupt pending flag) VIP (только Pentium) — устанавливается в 1 для индикации отложенного прерывания. Применяется при работе в режиме виртуального процессора i8086 совместно с флагом VIF (при CR4.VME = 1). Может быть установлен только программно, процессор лишь читает его.

Флаг идентификации (identification flag) ID — используется для того, чтобы показать факт поддержки процессором инструкции CPUID. Если программа может установить или сбросить этот флаг, то это означает, что данная модель процессора поддерживает инструкцию CPUID.

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

3. Используемое оборудование.

1. Персональный компьютер с минимальными системными требованиями:

- операционная система - Windows XP Professional SP3, Vista, Windows 7;

- процессор 3.00ГГц, и выше Pentium 4 и выше;

- RAM – 512 MБ и более;

- место на жестком диске – не менее 10 Мб;

- управление – мышь;

- видеокарта – IT Radion X1600 Pro и выше;

2. Интегрированная среда разработки программ на языке ассемблера, состоящая из следующих программных продуктов:

- специализированный пакет программирования на языке ассемблера   IA-32  MASM32;

- среда разработки RADasm (версия 2.2.1.1 и выше)

- 32-разрядный отладчик кода OllyDbg (версия 1.10 и выше).

4. Порядок работы со средой.

4.1. Начало работы со средой

Программная среда инициируется запуском программы RADAsm.exe.

После вызова на экране появляется окно среды RADAsm, в котором обычно высвечивается последняя программа, отлаживаемая предыдущий раз (см. рисунок 4.1).

Рисунок 4.1.  Окно интегрированной среды RADAsm

Для создания нового проекта необходимо выбрать пункт меню Файл/Новый проект, после чего на экране появится первое окно четырехоконного Мастера создания проекта (см. рисунок 4.2).

В этом окне необходимо выбрать тип проекта – в нашем случае Console App (консольное приложение), а также ввести его имя, например, Lab01, описание, например, «Лабораторная работа № 1», и путь к создаваемой средой новой папке с именем проекта.

 

Рисунок 4.2.  Окно мастера создания нового проекта

В следующем окне Мастера выбирается шаблон проекта – conapp.tpl – специально созданный для лабораторных работ шаблон консольного приложения.

Предпоследнее окно Мастера предлагает выбрать типы создаваемых файлов – выбираем Asm (исходные файлы ассемблера), и папки – выбираем папку Bak, используемую для размещения предыдущих копий файлов.

Последнее окно Мастера определяет доступные для работы с проектом пункты меню запуска приложения Создать и выполняемые команды. В данной сборке выполняемые команды уже настроены, поэтому в нем можно ничего не менять, хотя использоваться будут не все пункты созданного меню, а только следующие: Assemble (транслировать или, точнее, ассемблировать), Link (компоновать), Run (выполнить) и Run w/Debug (выполнить в подключенном отладчике).

В результате будет получена заготовка консольного приложения Windows. Просмотреть эту заготовку можно, дважды щелкнув левой клавишей мыши по файлу Lab01.asm в окне навигатора Project, расположенном справа вверху:

; Template for console application  - комментарий

        .586       ; подключение набора команд Реntium

        .MODEL  flat, stdcall ; модель памяти и

                     ; конвенция о передаче параметров

        OPTION CASEMAP:NONE ; опция различия строчных

                            ;  и прописных букв

Include kernel32.inc  ; подключение описаний процедур и 

Include masm32.inc    ; констант

IncludeLib kernel32.lib ; подключение библиотек

IncludeLib masm32.lib

        .CONST  ; начало раздела констант

MsgExit  DB    "Press Enter to Exit",0AH,0DH,0

        .DATA  ;раздел инициализированных переменных

        .DATA? ;раздел неинициализированных переменных

inbuf    DB    100 DUP (?)

        .CODE  ; начало сегмента кода

Start:

;                                  Место, куда  

;    Add you statements           добавляется код

;

        Invoke StdOut,ADDR MsgExit  ; вывод сообщения

        Invoke StdIn,ADDR inbuf,LengthOf inbuf  

                                 ; ввод строки

        Invoke ExitProcess,0    ; завершение программы 

        End    Start            ; конец модуля

Заготовку, как в других средах программирования, можно запустить на выполнение. Она содержит вызовы процедур, обеспечивающие вывод на экран запроса «Press Enter to Exit» (Нажмите клавишу Enter для выхода) и ввод строки. Это сделано для того, чтобы задержать автоматическое закрытие окна консоли при завершении программы до нажатия клавиши Enter.  

4.3. Запуск заготовки приложения

Для запуска заготовки необходимо выполнить:

  •  трансляцию Создать/Assemble,
  •  компоновку Создать/Link,
  •  запуск на выполнение  Создать/Run.

В процессе трансляции (ассемблирования) исходная программа на ассемблере преобразуется в двоичный эквивалент. Если трансляция проходит нормально, то в окне Output, которое появляется под окном программы, выводится текст:  

C:\Masm32\Bin\ML.EXE /c /coff /Cp /nologo

                     /I"C:\Masm32\Include" "Lab01.asm"

Assembling: Lab01.asm

Make finished.

Total compile time 78 ms

Примечание – Окно Output появляется и закрывается. Чтобы повторно посмотреть результаты, необходимо установить курсор мыши на верхнюю часть строки состояния под окном текста программы (нижнюю рамку окна Output). 

Первая строка сообщения об ассемблировании – вызов ассемблера:

C:\Masm32\Bin\ML.EXE – полное имя файла транслятора ассемблера masm32 (путь + имя), за которым следуют опции:

/c заказывает ассемблирование без автоматической компоновки,

/coff – определяет формат объектного модуля Microsoft (coff),

/Cp – означает сохранение регистра строчных и прописных букв всех идентификаторов программы,

/nologo – осуществляет подавление вывода сообщений на экран в случае успешного завершения ассемблирования,

/I"C:\Masm32\Include" – определяет местонахождение вставляемых (.inc) файлов,

и параметр "Lab01.asm" – задает имя обрабатываемого файла.

Остальные строки – сообщение о начале и завершении процесса ассемблирования и времени выполнения этого процесса.

Результатом нормального завершения ассемблирования является создание файла, содержащего объектный модуль программы, – файла Lab01.obj.

Если при ассемблировании обнаружены ошибки, то объектный модуль не создается и после сообщения о начале ассемблирования идут сообщения об ошибках, например:

Lab01.asm(26) : error A2006: undefined symbol : EAY

В сообщении  указывается:

  •  номер строки  исходного текста (в скобках),
  •  номер ошибки, под которым она описана в документации,
  •  возможная причина.

После исправления ошибок процесс ассемблирования повторяют.

Следующий этап – компоновка программы. На этом этапе к объектному (двоичному) коду программы добавляются объектные коды используемых подпрограмм. При  этом в тех местах программы, где происходит вызов процедур, указывается их относительный адрес в модуле. Сведения о компоновке также выводятся в окно Output:

C:\Masm32\Bin\LINK.EXE /SUBSYSTEM:CONSOLE /RELEASE

/VERSION:4.0 /LIBPATH:"C:\Masm32\Lib"  /OUT:"Lab01.exe" "Lab01.obj"

Microsoft (R) Incremental Linker Version 5.12.8078

Copyright (C) Microsoft Corp 1992-1998. All rights reserved.

Make finished.

Total compile time 109 ms

Первая строка вывода также является командной строкой вызова компоновщика

C:\Masm32\Bin\LINK.EXE – полное имя компоновщика, за которым следуют опции:

/SUBSYSTEM:CONSOLE – подключить стандартное окно консоли,

/RELEASE – создать реализацию (а не отладочный вариант),

/VERSION:4.0 – минимальная версия компоновщика,

/LIBPATH:"C:\Masm32\Lib" – путь к файлам библиотек,

/OUT:"Lab01.exe" – имя результата компоновки – загрузочного файла

и параметр "Lab01.obj" – имя объектного файла.

В следующих строках также возможны сообщения об ошибках. В основном в лабораторных работах вы будете получать сообщение о неразрешенных внешних ссылках, например:

Lab01.obj:error LNK2001:unresolved external symbol _ExitProcess@4

Lab01.exe : fatal error LNK1120: 1 unresolved externals

Make error(s) occured.

Как правило, такое сообщение говорит о наличии в программе вызовов процедур, для которых в указанных библиотеках не найдены коды. В данном примере не подключена библиотека, в которой находится процедура  ExitProcess.

После устранения ошибки программу необходимо перетранслировать и заново скомпоновать.

Если процессы трансляции и компоновки прошли нормально, то ее можно запустить на выполнение. При этом открывается окно консоли, в которое выводится строка запроса (см. рисунок 4.3).

Рисунок 4.3.  Окно консоли

Окно закрывается при нажатии клавиши Enter.

4.4. Создание простейшей программы

Для изучения возможностей отладчика необходимо ввести программу, которая выполняет несколько простых команд, например, вычисляет результат следующего выражения:

X=A+5-B

Данные для программы зададим константами, поместив их описание в раздел инициированных данных:

         .DATA

A         SDWORD  -30

B         SDWORD  21

Для результата вычислений – переменной X – необходимо зарезервировать место, поместив описание соответствующей  неинициализированной переменной в раздел неинициализированных данных:

         .DATA?

X         SDWORD  ?

Размещение неинициализированной переменной в этом разделе не обязательно, но более грамотно, поскольку неинициализированные переменные в образе исполняемой программы на диске не хранятся, а размещаются при загрузке на выполнение.

фрагмент кода программы, выполняющей сложение и вычитание, необходимо поместить в сегменте кодов после метки Start:

Start:    mov    EAX,A ; поместить число в регистр EAX

         add    EAX,5;сложить EAX и 5, результат в EAX

         sub    EAX,B ;вычесть B, результат в EAX

         mov    X,EAX ; сохранить результат в памяти

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

4.4.  Просмотр выполнения программы в отладчике

Для запуска программы в режиме отладки следует последовательно инициировать следующие пункты меню:

  •  трансляцию Создать/Assemble,
  •  компоновку Создать/Link,
  •  запуск на выполнение в отладчике  Создать/Run w/Debug.

После запуска на экране появляется окно отладчика OlleDBG (см. рисунок 4).  

Рисунок 4.4.  Окно OllyDbg.

В окне можно выделить четыре области:

  •  дочернее окно CPU – окно процессора, в котором высвечиваются адреса команд, их шестнадцатеричные коды, результаты дисассемблирования и результаты выделения параметров процедур;
  •  область Registers – окно содержимого регистров процессора,
  •  окно данных, в котором высвечиваются адреса памяти (Address) и ее шестнадцатеричный (Hex dump) и символьный (ASCII) дампы;
  •  окно стека, в котором показывается содержимое вершины стека.

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

F7 – выполнить шаг с заходом в тело процедуры;

F8 – выполнить шаг, не заходя в тело процедуры.

Адрес начала программы 00401000h. К сожалению, отладчик не всегда правильно дисассемблирует двоичный код программы, и какие-то команды могут остаться не распознанными. Однако выполнение программы будет осуществляться правильно.

Адрес начала раздела инициированных данных – 00403000h.  Каждое значение занимает столько байт, сколько резервируется директивой. В отладчике каждый байт представлен двумя шестнадцатеричными цифрами. Кроме того, используется обратный порядок байт, т.е. младший байт числа находится в младших адресах памяти (перед старшим). Если шестнадцатеричная комбинация соответствует коду символа, то он высвечивается в следующем столбце (ASCII), иначе в нем высвечивается точка.

Не инициированные данные располагаются после инициированных с адреса, кратного 16.

При каждом выполнении команды мы можем наблюдать изменение данных в памяти и/или в регистрах, отслеживая процесс выполнения программы и контролируя правильность промежуточных результатов.

Так после выполнения первой команды число A копируется в регистр EAX, который при этом подсвечивается красным. При записи в регистр порядок байт меняется на прямой, при котором первым записан старший байт.

4.5. Описание данных в программе на ассемблере

Все данные, используемые в программах на ассемблере, обязательно должны быть описаны.

Директива описания данных имеет следующий формат:

[<Имя>] <Директива>[<Константа>DUP(]<Список инициализаторов>[)]

где  <Имя> – имя поля данных, которое может не присваиваться;

<Директива> – команда, объявляющая тип описываемых данных (см. таблицу 1);

<Константа> DUP – используются при описании повторяющихся данных, тогда константа определяет количество повторений;

      <Список инициализаторов> – последовательность инициализирующих констант, указанных через запятую, или символ «?», если инициализирующее значение не определяется.

Примечание – В качестве директив также могут использоваться:

  •  DB определить байт,
  •  DW определить слово,
  •  DDопределить двойное слово (4 байта),
  •  DQопределить четыре слова (8 байт),
  •  DT определить 10 байт,

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

Таблица 1 – Директивы определения данных

 Директива

Описание типа данных

BYTE

8-разрядное целое без знака

SBYTE

8-разрядное целое со знаком

WORD

16-разрядное целое без знака или ближний указатель RM

SWORD

16-разрядное целое со знаком

DWORD

32-разрядное целое без знака или ближний указатель

SDWORD

32-разрядное целое со знаком

Таблица 1 – Директивы определения данных (Окончание)

 Директива

Описание типа данных

FWORD

48-разрядное целое или дальний указатель

QWORD

64-разрядное целое

TBYTE

80-разрядное целое

Real4

32-х разрядное короткое вещественное

Real8

64-х разрядное длинное вещественное

Real10

80-ти разрядное расширенное вещественное

В качестве инициализаторов при описании данных применяются:

  •  целые константы [<знак>]<целое> [<основание системы счисления>],

например:

  •  -43236, 236d  – целые десятичные числа,
    •  23h, 0ADh – целые шестнадцатеричные числа (если шестнадцатеричная константа начинается с буквы, то перед ней указывается 0),
    •  0111010bцелое двоичное;
  •  вещественные константы [<знак>] <целое> . [E|e [<знак>] <целое>],

например: -2., 34E-28;

  •  символы в кодировке ASCII (MS DOS) или ANSI (Windows) в апострофах или кавычках, например: 'A' или A;
  •  строковые константы в апострофах или кавычках, например, 'ABCD' или ABCD.

Примеры определения данных различных типов приведены далее.

5. Порядок выполнения работы.

  1.  Запустите RADAsm, создайте файл проекта по шаблону консольного приложения. Внимательно изучите структуру программы и зафиксируйте текст с комментариями в отчете.
  2.  Запустите шаблон на выполнение и просмотрите все полученные сообщения. Убедитесь, что текст программы и настройки среды не содержат ошибок.
  3.  Добавьте директивы определения данных и команды сложения и вычитания, описанные в разделе 3 настоящих методических указаний. Найдите в отладчике внутреннее представление исходных данных, зафиксируйте его в отчете и поясните.

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

  1.  Введите следующие строки в раздел описания инициированных данных и определите с помощью отладчика внутренние представление этих данных в памяти. Результаты проанализируйте и  занесите в отчет.

val1    BYTE   255

chart   WORD   256  

lue3   SWORD  -128

alu     BYTE   ?  

v5      BYTE   10h  

       BYTE   100101B  

beta    BYTE   23,23h,0ch

sdk     BYTE   ²Hello²,0

min     SWORD  -32767

ar      DWORD  12345678h   

valar   BYTE   5 DUP (1, 2, 8)

  1.  Определите в памяти следующие данные:

а) целое число 25 размером 2 байта со знаком;

б) двойное слово, содержащее число -35;

в) символьную строку, содержащую ваше имя (русскими буквами и латинскими буквами).

Зафиксируйте в отчете внутреннее представление этих данных и дайте пояснение.

  1.  Определите несколькими способами в программе числа, которые во внутреннем представлении (в отладчике) будут выглядеть как 25 00 и 00 25. Проверьте правильность ваших предположений, введя соответствующие строки в программу. Зафиксируйте результаты в отчете.
  2.  Замените директивы описания знаковых данных на беззнаковые:

A        DWORD  -30

B        DWORD  21

X        DWORD  ?

Запустите программу и прокомментируйте результат.

  1.  Добавьте в программу переменную F1=65535 размером слово и переменную F2= 65535 размером двойное слово. Вставьте в программу команды сложения этих чисел с 1:

     add   F1,1

     add   F2,1

Проанализируйте и прокомментируйте в отчете полученный результат (обратите внимание на флаги).

Литература

  1.  Ирвин К. Язык ассемблера для процессоров Intel. – М.: Изд. дом «Вильямс», 2005.
  2.  Зубков С.В. Assembler для DOS, Windows и Unix. – М.: ДМК Пресс, 2004.
  3.  Пирогов В.Ю. Ассемблер. Учебный курс. – СПб.: БХВ-Петербург, 2003.
  4.  Финогенов К.Г., Рудаков П.И. Язык Ассемблера: уроки программирования. – М.: Диалог-МИФИ, 2001.
  5.  Юров В.И. Справочник по языку Ассемблера IBM PC. – CПб.: Питер, 2004.

PAGE 32


 

А также другие работы, которые могут Вас заинтересовать

12152. КОМПОНЕНТЫ, ИСПОЛЬЗУЕМЫЕ ДЛЯ СВЯЗИ С БАЗАМИ ДАННЫХ 66 KB
  КОМПОНЕНТЫ ИСПОЛЬЗУЕМЫЕ ДЛЯ СВЯЗИ С БАЗАМИ ДАННЫХ Обзор компонентов используемых для связи с базами данных Компоненты Delphi используемые для работы с базами данных расположены в библиотеке компонентов на страницах Data Access доступ к данным и Data Control управл
12153. Знакомство с интегрированной средой Delphi 136 KB
  Лабораторная работа № 1 Знакомство с интегрированной средой Delphi Загрузка Delphi возможна одним из следующих способов: кнопка Пуск раздел Программы и далее в соответствии с названием программного продукта; ярлык на рабочем столе; быстрая кнопк
12154. СОЗДАНИЕ ОТЧЕТОВ. Система «Быстрый отчет» (Quick Report) 96.18 KB
  СОЗДАНИЕ ОТЧЕТОВ 6.1 Система Быстрый отчет Quick Report Для создания отчетов в Delphi включена система QuickReport все компоненты которой размещены на странице QReport палитры компонентов. Быстрый отчет использует генератор отчетов состоящий из множества полос. Полоса band э
12155. ПРОГРАММИРОВАНИЕ РАБОТЫ С БАЗАМИ ДАННЫХ 70.04 KB
  ПРОГРАММИРОВАНИЕ РАБОТЫ С БАЗАМИ ДАННЫХ Состояние набора данных Основным свойством компонента Table является свойство State определяющее состояние набора данных. Это свойство доступно только во время выполнения и только для чтения. Набор данных может находиться...
12156. ПРИЛОЖЕНИЯ С НЕСКОЛЬКИМИ СВЯЗАННЫМИ ТАБЛИЦАМИ 31.5 KB
  ПРИЛОЖЕНИЯ С НЕСКОЛЬКИМИ СВЯЗАННЫМИ ТАБЛИЦАМИ Рассмотрим принципы построения приложения с несколькими связанными друг с другом таблицами. 8.1 Связь головной и вспомогательной таблиц Две таблицы могут быть связаны друг с другом по ключу. Одна из этих связанных табл...
12157. ТИПЫ ПОЛЕЙ. НЕКОТОРЫЕ СВОЙСТВА ТАБЛИЦЫ 61.5 KB
  ТИПЫ ПОЛЕЙ. НЕКОТОРЫЕ СВОЙСТВА ТАБЛИЦЫ Типы полей реляционной базы данных Проектирование приложения работающего с базами данных предполагает наличие самих баз данных. Вместе с BDE в Delphi поставляется программа Database Desktop которая позволяет создавать таблицы ба...
12158. ОБЩЕЕ ПОНЯТИЕ О БАЗЕ ДАННЫХ. МОДЕЛИ ДАННЫХ. СИСТЕМЫ УПРАВЛЕНИЯ БАЗАМИ ДАННЫХ 182.07 KB
  ОБЩЕЕ ПОНЯТИЕ О БАЗЕ ДАННЫХ. МОДЕЛИ ДАННЫХ. СИСТЕМЫ УПРАВЛЕНИЯ БАЗАМИ ДАННЫХ База данных Всегда когда возникает потребность манипулирования большими массивами данных используются базы данных. В общем случае под данными понимается информация наход...
12159. ПОСТРОЕНИЕ ЗАПРОСОВ В DELPHI 36 KB
  ПОСТРОЕНИЕ ЗАПРОСОВ В DELPHI Запрос это вопрос к базе данных возвращающий запись или множество записей удовлетворяющих вопросу. Любой запрос по базе данных выполняется на языке SQL Structured Query Language язык структурированных запросов который был создан Microsoft в конце 70х год...
12160. Режимы design-time и run-time. Объектные процедурные типы. Работа с ini файлами 148.5 KB
  Лабораторная работа №1 Тема: Режимы designtime и runtime. Объектные процедурные типы. Работа с iniфайлами Цель работы: показать простоту создания приложений в режиме designtime и удобство использования компонентов; показать возможность создания приложений с настраиваемым интер...