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

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

.pdf
Скачиваний:
1
Добавлен:
08.09.2026
Размер:
2 Мб
Скачать
Министерство транспорта Российской Федерации
Федеральное государственное автономное образовательное
учреждение высшего образования
«Российский университет транспорта»
___________________________________________________________
В.А. ВАРФОЛОМЕЕВ
РАЗРАБОТКА ПРИЛОЖЕНИЙ НА ЯЗЫКЕ
АССЕМБЛЕР В СРЕДЕ
MS MASM
Учебно-методическое пособие для бакалавров направлений
"Информатика и вычислительная техника"
и "Информационные системы и технологии"
М О С К В А - 2021
1
УДК 681.3.066 В18
Варфоломеев В.А. Разработка приложений на языке ассемблер в среде MS MASM: Учебно-методическое пособие по дисциплинам "Ассемблер" и «Операционные системы и системное программирование». — М.: РУТ (МИИТ), 2021. — 59 с.
В учебно-методическом пособии представлен лабораторный практи­кум, состоящий из пяти лабораторных работ по изучению средств разра­ботки и написания программ на языке ассемблер для современных персо­нальных компьютеров на базе микропроцессора Intel с использованием среды программирования Макро Ассемблер (MASM).
Рецензент: к.т.н., доцент каф. «Вычислительные системы, сети и ин­формационная безопасность» РУТ (МИИТ) Шамров Михаил Иванович.
© РУТ (МИИТ), 2021
2
СОДЕРЖАНИЕ
ВВЕДЕНИЕ ....................................................................................................... 5
1 ОСНОВНЫЕ ПОНЯТИЯ ........................................................................... 6
1.1 Машинный язык и язык ассемблер ...................................................... 6
1.2 Синтаксис языка ассемблер .................................................................. 7
1.3 Структура программы на языке ассемблер ......................................... 8
2 СРЕДСТВА РАЗРАБОТКИ ПРИЛОЖЕНИЙ НА ЯЗЫКЕ АССЕМБЛЕР.
ЛАБОРАТОРНАЯ РАБОТА №1 ................................................................... 10
2.1 Пример простейшей программы на языке ассемблер ...................... 10
2.2 Этапы разработки программ на ассемблере ...................................... 12
2.3 Рабочее задание и порядок выполнения работы ............................... 15
2.3.1 Установка программного обеспечения MASM ............................. 15
2.3.2 Создание EXE файла ........................................................................ 15
2.3.3 Использование отладчика ................................................................ 16
2.3.4 Представление данных в ассемблере ............................................. 17
2.4 Использование командных файлов .................................................... 20
2.5 Требования к отчету ............................................................................. 22
2.6 Контрольные вопросы .......................................................................... 22
3 АРИФМЕТИЧЕСКИЕ ВЫЧИСЛЕНИЯ. ЛАБОРАТОРНАЯ РАБОТА
№2. .................................................................................................................... 24
3.1 Флаги ...................................................................................................... 24
3.2 Арифметические команды ................................................................... 24
3.2.1 Команда сложения ADD .................................................................. 25
3.2.2 Команда вычитания SUB ................................................................. 25
3.2.3 Команды умножения MUL, IMUL .................................................. 26
3.2.4 Команды деления DIV, IDIV ........................................................... 27
3.2.5 Команды преобразования типа MOVSX, MOVZX ....................... 27
3.3 Команды сравнения и передачи управления ..................................... 28
3.3.1 Команда безусловного перехода JMP ............................................ 28
3.3.2 Команда сравнения CMP ................................................................. 28
3.3.3 Команды условного перехода ......................................................... 29
3.4 Рабочее задание..................................................................................... 30
3.5 Требования к отчету ............................................................................. 32
3.6 Контрольные вопросы .......................................................................... 32
3.7 Пример программы ............................................................................... 33
4 БИТОВЫЕ ОПЕРАЦИИ. ЛАБОРАТОРНАЯ РАБОТА №3 .................. 34
4.1 Команды логических операций AND, TEST, OR, XOR, NOT ......... 34
4.2 Команды сдвига .................................................................................... 35
4.2.1 Логический сдвиг SHR, SHL ........................................................... 35
4.2.2 Арифметический сдвиг SAR, SAL .................................................. 36
4.2.3 Циклический сдвиг ROR, ROL ....................................................... 37
3
4.3 Типовые задачи использования битовых операций .......................... 37
4.3.1 Проверка значения бита ................................................................... 37
4.3.2 Установка единичного значения бита ............................................ 38
4.3.3 Установка нулевого значения (сброс) бита ................................... 38
4.3.4 Инвертирование значения бита ....................................................... 39
4.3.5 Перемещение битов числа ............................................................... 39
4.4 Рабочее задание..................................................................................... 40
4.5 Требования к отчету ............................................................................. 41
4.6 Контрольные вопросы .......................................................................... 41
5 ОБРАБОТКА МАССИВОВ. ЛАБОРАТОРНАЯ РАБОТА №4 ............ 42
5.1 Описание и инициализация массивов ................................................ 42
5.2 Доступ к элементам одномерного массива ........................................ 42
5.3 Доступ к элементам двумерного массива .......................................... 43
5.4 Организация циклов: команда LOOP ................................................. 44
5.5 Рабочее задание..................................................................................... 45
5.6 Требования к отчету ............................................................................. 46
5.7 Контрольные вопросы .......................................................................... 47
5.8 Пример программы ............................................................................... 47
6 ПРОЦЕДУРЫ. ЛАБОРАТОРНАЯ РАБОТА №5. .................................. 49
6.1 Механизм вызова процедур ................................................................. 49
6.2 Работа со стеком ................................................................................... 49
6.2.1 Запись в стек ...................................................................................... 50
6.2.2 Чтение из стека ................................................................................. 51
6.3 Создание и использование процедур.................................................. 52
6.3.1 Описание процедуры ........................................................................ 52
6.3.2 Вызов процедуры .............................................................................. 52
6.3.3 Возврат из процедуры ...................................................................... 52
6.4 Организация интерфейса с процедурой ............................................. 53
6.5 Рабочее задание..................................................................................... 54
6.6 Требования к отчету ............................................................................. 55
6.7 Контрольные вопросы .......................................................................... 55
6.8 Пример программы ............................................................................... 57
СПИСОК ИСПОЛЬЗОВАННЫХ ИСТОЧНИКОВ...................................... 59
4
ВВЕДЕНИЕ
Данное учебно-методическое пособие посвящено практическому изу­чению ассемблера - низкоуровневого языка программирования. «Низко­уровневость» означает, что доступный программисту набор команд ассем­блера однозначно соответствует набору так называемых «машинных» ко­манд, которые представляются в двоичном коде и могут быть поняты и ис­полнены процессором. Ассемблер всего лишь позволяет записать машин­ные команды в более понятном человеку символическом виде.
Чем интересен и полезен современному специалисту ассемблер? В первую очередь, возможностью написания эффективных программ в пол­ной мере использующих особенности архитектуры современных компью­теров. Эффективность выражается в более экономном использовании ре­сурсов компьютера (в первую очередь оперативной памяти) и повышении производительности вычислений. На ассемблере пишут аппаратно-зависи­мые модули в составе операционной системы, программы управления ин­теллектуальными устройствами и микроконтроллерами. Для прикладного программиста существует возможность включать в проект, разрабатывае­мый, например, на высокоуровневом языке С++, отдельные модули, напи­санные на ассемблере для существенного повышения быстродействия про­грамм.
Однако есть еще одна важная причина, по которой следует познако­миться с ассемблером. Изучение особенностей построения и реализации ас­семблерных программ дает наглядный способ практического знакомства с базовыми понятиями и глубинными механизмами функционирования со­временных вычислительных систем на аппаратном уровне и на уровне опе­рационной системы, без понимания которых не может получиться квали­фицированный специалист. Именно эта цель и ставится перед студентами, приступающими к изучению ассемблера.
В данном пособии представлено 5 лабораторных работ по базовым вопросам разработки программ и использования основных алгоритмиче­ских конструкций в ассемблере. В качестве инструментального средства для разработки используется макроассемблер компании Microsoft (MASM). Особое внимание уделено использованию отладчика для получения деталь­ной информации о содержимом памяти программы в процессе выполнения.
Следует отметить, что пособие содержит справочные сведения, каса­ющиеся исключительно тем, представленных в лабораторных работах, и не может быть использовано для изучения всех элементов языка в полном объ­еме. Обязательно необходимо использовать дополнительные источники, включая лекционные материалы и рекомендованную литературу.
Автор выражает благодарность студенту Панферову В.Д. (УВА-311,
2019) за помощь при подготовке примеров программ.
5
1 ОСНОВНЫЕ ПОНЯТИЯ
1.1 Машинный язык и язык ассемблер
Как известно, компьютерная программа представляет собой последо­вательность команд (инструкций), которые "объясняют" компьютеру, что он должен делать. Программа, запущенная на выполнение, должна быть размещена в оперативной памяти компьютера в виде совокупности входя­щих в нее команд, записанных на машинном языке. Машинный язык – это система представления в двоичном коде всех поддерживаемых процессо­ром команд. Машинный язык - единственный язык, который машина пони­мает, причем каждая модель процессора имеет свой собственный машин­ный язык. Процессор извлекает команды машинного языка из оперативной памяти в определенной последовательности и выполняет их. Например, машинная команда сложения двух чисел, хранящихся в ре­гистрах процессора AX и BX, будет представлена в оперативной памяти в виде двухбайтового двоичного числа 000001111000011b. Эти два байта
точно указывают процессору, какую операцию произвести, где размещены исходные данные и куда поместить результат.
Регистры процессора – это ячейки сверхбыстрой памяти внутри про­цессора, предназначенные для хранения исходных данных и результатов вычислений, а также для связи процессора с другими устройствами компь­ютера. К данным, сохраненным в регистрах, процессор получает доступ очень быстро - намного быстрее, чем к данным, хранимым в оперативной памяти. Для всех регистров процессора установлены стандартные символи­ческие имена, например, AX, BX, ESI, EDI, DS, CS и др. Различают реги­стры общего назначения, которые можно использовать в программе произ­вольно, и специальные регистры, которые предназначены для определен­ных целей. Язык ассемблер - это язык программирования, основанный на исполь­зовании символьной формы записи команд машинного языка. Каждой ма­шинной команде соответствует определенная команда ассемблера, пред­ставленная мнемокодом, в котором указывается код выполняемой опера­ции и операнды. Например, рассмотренная выше команда сложения содер­жимого регистров AX и BX на языке ассемблер будет записана так:
ADD AX,BX
Код операции ADD происходит от английского «addition» (сложение), а операнды представлены регистрами процессора AX и BX.
Программа, записанная на языке ассемблер, относительно легко вос­принимается человеком, но не может быть непосредственно выполнена компьютером. Для выполнения ассемблерной программы сначала необхо­димо осуществить ее перевод на машинный язык. Этот процесс, называется ассемблированием программы. Операцию перевода с языка ассемблер на
6
машинный язык выполняет специальная программа, называемая ассембле- ром. Язык ассемблер является машинно-зависимым, так как программы, написанные на этом языке, непосредственно относятся к тому типу процес­сора, на котором они должны выполняться. Язык ассемблер для персональ­ного компьютера, использующего микропроцессоры фирмы Intel (или AMD), принципиально отличен от языка ассемблер для других компьюте­ров. Более того, существуют некоторые различия между языками ассемблер для персональных компьютеров, использующих различные модели микро­процессоров Intel (например, i386, Pentium IV или Core i7). Наиболее важ­ное отличие заключается в максимальном размере используемых реги­стров: 16 разрядов (2 байта) для первых моделей процессора; 32 разряда (4 байта) для моделей, начиная с i386; 64 разряда (8 байт) для современных моделей. Именно разрядность регистров определяет понятие «разрядность компьютера».
1.2 Синтаксис языка ассемблер
Команда языка ассемблер состоит из четырех частей и имеет вид:
Метка КОП Операнды Комментарий
Вот пример типичной команды:
PART1: ADD AX,BX ;Добавить к длине буфера
Единственная обязательная часть команды языка ассемблер - код опе­рации (КОП), определяющий, какую операцию должен будет выполнить
процессор. В нашем примере ADD указывает на операцию сложения. Поле операндов содержит дополнительную информацию о команде, например, какие значения участвуют в операции. Каждому коду операции должно соответствовать определенное число операндов определенного типа. Для команды ADD требуется два операнда; операция перемены знака (NEG) обходится лишь одним, а для некоторых команд, например, команды преобразования типа числа CBW, операнды не указываются вовсе. В каче­стве операндов могут использоваться регистры процессора, переменные, адреса памяти, задаваемые непосредственно числовые и символьные зна­чения. Поля метки и комментария – необязательные поля в команде. Метка позволяет обозначить какое-либо конкретное место в тексте программы для последующих ссылок на него. Фактически метка является символическим указателем на расположение команды в оперативной памяти, принимая значение адреса соответствующей ячейки. Использование меток - одна из причин предпочтительности языка ассемблер перед машинным языком. Превращением же символических имен в реальные адреса ведает ассем­блер.
7
Поле комментария начинается с символа ";" и служит для записи произвольного текста, поясняющего смысл выполняемого в команде дей-
ствия. Существует возможность отвести под комментарий целую строку, поставив в ее начале символ ";". Это позволяет программисту включить в
текст программы блок собственной информации, к примеру, описание ис­пользуемого алгоритма и т.п..
Помимо команд язык ассемблер включает специальные инструкции ­директивы. Директивы не являются частью выполняемой программы, а предназначены для программы-ассемблера, который должен выполнять их во время ассемблирования. Директивы не преобразуются в машинные ко­манды.
Формат директив схож с форматом представления команд, но может иметь некоторые особенности, которые здесь не рассматриваются.
1.3 Структура программы на языке ассемблер
Программа, написанная на языке ассемблер, представляется в виде со­вокупности блоков, называемых сегментами. Обычно программа включает три сегмента: сегмент данных, сегмент кода и сегмент стека. При размеще­нии программы в оперативной памяти каждому сегменту будет предостав­лена отдельная область памяти.
Сегмент данных программы служит для описания и инициализации переменных и обеспечивает возможность резервирования необходимого количества ячеек памяти для их размещения в памяти. Начало сегмента данных обычно помечают директивой .data.
Сегмент кода программы содержит записанные программистом ко­манды. Начало сегмента кода обычно помечают директивой .code.
Сегмент стека служит для резервирования памяти для временного хранения данных программы при вызове подпрограмм, обработке прерыва­ний и т.п. Начало сегмента стека обычно помечают директивой .stack.
Способ размещения сегментов программы в оперативной памяти определяется выбранной моделью памяти, задаваемой с помощью дирек­тивы .model. Микропроцессор Intel реализует две основные модели: сег-
ментированную и плоскую.
В сегментированной модели памяти, используемой для 16-разрядных процессоров, для каждого сегмента программы (данные, код, стек) можно было выделить отдельный сегмент оперативной памяти размером не более 64 Кб. Для формирования адреса каждого сегмента использовались сег­ментные регистры: DS – для сегмента данных, CS – кода, SS – стека. Адрес
любой ячейки памяти в сегменте записывался в виде P:D, где величина P задает позицию начала сегмента, а величина D задает смещение ячейки внутри выбранного сегмента. Поскольку установлено, что начало любого
8
сегмента должно приходится на ячейку с абсолютным адресом S, кратным 16 (10h), величина P определяется, как S/16. Например, если абсолютный адрес начала сегмента равен 144=90h, то позиция начала сегмента P будет равна 9. Адрес первой ячейки данного сегмента будет записан так: 9:0 (сме­щение D равно 0), следующей за ней – 9:1 и т.д.
Именно для хранения сегментной составляющей адреса P служат сег­ментные регистры микропроцессора Intel. Позиция начала сегмента данных в памяти задается с помощью сегментного регистра DS, так что адрес пер-
вой переменной, объявленной в сегменте данных, будет записан как DS:0. Ячейки сегмента кода адресуются с помощью пары регистров CS:IP. Сег­ментный регистр CS задает позицию начала сегмента кода в памяти. 16­разрядный регистр IP служит для указания относительного адреса (смеще­ния) очередной выполняемой машинной команды в сегменте кода. Содер-
жимое регистра IP изменяется в ходе выполнения программы автоматиче­ски путем добавления к текущему значению величины, равной длине (в
байтах) выполненной команды.
Плоская модель памяти (flat) используется для 32 (64)-разрядных процессоров и заключается в создании упрощенных по структуре про­грамм, в которых данные, код и стек размещаются в одном сегменте па­мяти, но в разных его участках. Для 32-разрядных процессоров максималь­ный размер сегмента памяти равен 4 Гб, для 64-разрядных – 16 Еб. Для ад­ресации команд используется 32-разрядный регистр EIP или 64-разряд-
ный RIP, в котором всегда хранится адрес следующей выполняемой ко­манды. На рисунке 1.1 показано, как будут размещены в памяти исполни-
мые программы при использовании сегментированной и плоской моделей памяти.
Сегментированная модель памяти
DS:0
CS:0
SS:0
Сегмент данных
Сегмент кода
Сегмент стека
Плоская модель памяти
0
Данные, код,
стек
Рисунок 1.1 - Размещение программы в памяти
9
2 СРЕДСТВА РАЗРАБОТКИ ПРИЛОЖЕНИЙ НА ЯЗЫКЕ АССЕМБЛЕР. ЛАБОРАТОРНАЯ РАБОТА №1
Содержание работы:
- знакомство с общими принципами создания программ на языке ас-
семблер;
- практическое освоение средств системы программирования Макро
Ассемблер (MASM);
- практическое изучение работы с отладчиком OllyDebug.
2.1 Пример простейшей программы на языке ассемблер
Рассмотрим, как выглядит простейшая оконная программа на языке ассемблер, которая предназначена для вывода на экран фразы: «Здрав­ствуйте, это я, ХХХХХ!», где ХХХХХ - Ваши имя и фамилия.
Текст программы представлен на рисунке 2.1.
;Лабораторная работа №1 (1)
;Выполнил ст. гр. УВА-313 Панферов В.Д. (2) ;Программа 1 (HELLO.ASM) Вариант №1 (3)
.486 (4) .model flat, stdcall ;Тип используемой модели памяти (5) option casemap: none (6)
.stack 100h ;Определяется сегмент стека размером 256 байт (7)
;Подключение необходимых системных модулей и библиотек (8) include c:\masm32\include\windows.inc (9) include c:\masm32\include\user32.inc (10) include c:\masm32\include\kernel32.inc (11) includelib c:\masm32\lib\user32.lib (12) includelib c:\masm32\lib\kernel32.lib (13) .data ;Начало сегмента данных (14) tit db 'Привет, мир',0 ;Переменная - заголовок окна (15) hello db'Здравствуйте, я Панферов!',0;Резервируется память (16) ;для переменной Hello
.code ;Начало сегмента кода (17) main: ;Метка, обозначающая точку входа в программу (18 push 0 ;Дескриптор окна (19) push offset tit ;Заголовок окна (20) push offset hello ;Текст для вывода (21) push 0 ;Стиль окна (0 – окно с кнопкой ОК) (22) call MessageBox ;Вызов функции вывода на экран (23) push 0 ;Код завершения (24) call ExitProcess ;Завершаем работу программы (25) end main (26)
Рисунок 2.1 – Исходный код программы hello.asm
10
Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]