Files
ovt3-masm-strings/task.md
T

412 lines
22 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Лабораторная работа №3
## Строковые операции в MASM32
**Дисциплина:** Основы вычислительной техники и операционные системы
автоматизированных технологических комплексов (Б1.В.01)
**Направление:** 15.03.06 «Мехатроника и робототехника»
**Семестр:** 3 · **Объём:** 4 часа аудиторных + самостоятельная работа
**Среда:** MASM32 (редактор QEditor / сборка `ml` + `link`), отладчик OllyDbg
---
## 1. Цель работы
Получение навыков программирования на языке Assembler для Win32,
в частности освоение команд работы со строками (цепочечных команд)
и их практического применения в операциях поиска, копирования,
изменения данных.
**Задачи:**
- освоить цепочечные команды `MOVS`, `LODS`, `STOS`, `SCAS`, `CMPS`
и префиксы повторения `REP`/`REPE`/`REPNE`;
- научиться создавать GUI-приложение Win32 на MASM32 (главное окно,
поле ввода, кнопка, обработка сообщений);
- реализовать индивидуальный вариант обработки строки с вводом и
выводом в диалоговом окне Windows;
- провести вычислительный эксперимент и убедиться в правильности
результата.
---
## 2. Задание
Разработать алгоритм и программу на языке Assembler для Win32
в соответствии с **индивидуальным заданием** (см. раздел 5, вариант
выдаёт преподаватель). Ввод и вывод осуществить **в диалоговом окне
Windows**.
Работа состоит из пяти частей.
### Задание 1. Окно Windows: ввод и вывод — 2 балла
Создать GUI-приложение Win32 на MASM32:
1. Стандартная «шапка» программы: `.386`, `.model flat, stdcall`,
`option casemap:none`, подключение `windows.inc`, `user32.inc`,
`kernel32.inc` и соответствующих `.lib`.
2. В `WinMain`: заполнить структуру `WNDCLASSEX`, зарегистрировать
класс (`RegisterClassEx`), создать окно (`CreateWindowEx`),
показать его (`ShowWindow`) и запустить цикл сообщений
(`GetMessage` / `TranslateMessage` / `DispatchMessage`).
3. В оконной функции `WndProc` обработать:
- `WM_DESTROY` — выход из программы (`PostQuitMessage`);
- `WM_CREATE` — создать **поле ввода** (класс `edit`) и
**кнопку** (класс `button`) с уникальными ID.
4. Обработать `WM_COMMAND`: получить строку из поля ввода
(`GetWindowText` в буфер) и вывести результат обработки обратно
в поле (`SetWindowText`) или в `MessageBox`.
> Подробное описание создания окна, регистрации класса, структуры
> `WNDCLASSEX`, создания дочерних элементов `edit`/`button`, разбора
> `WM_COMMAND` и функций `GetWindowText`/`SetWindowText` — в
> дополнительном материале **«Программирование на Ассемблере в Win32»**
> (файл `Окна в MASM32.PDF`, разделы 9, 10, 14).
**Проверка:** программа собирается и запускается; окно содержит поле
ввода и кнопку; закрытие окна завершает процесс.
### Задание 2. Алгоритм варианта — 2 балла
По номеру варианта (раздел 5) разработать алгоритм:
- определить тип обработки: одну строку, числа в тексте, слова или
две строки;
- выбрать направление просмотра (`CLD`) и регистры: `ESI` — источник,
`EDI` — приёмник результата, `ECX` — счётчик;
- указать, какие цепочечные команды применяются на каждом шаге и как
меняются `EDI`/`ESI`/`ECX`;
- предусмотреть крайний случай (пустая строка / конец данных).
Оформить блок-схему или пошаговое описание алгоритма.
**Проверка:** алгоритм соответствует варианту; указаны начальные
регистры и результат.
### Задание 3. Программа — 2 балла
Реализовать алгоритм на MASM32. **Обязательно** использовать
цепочечные команды и префикс повторения:
| Команда | Назначение |
|---------|------------|
| `MOVS` (`MOVSB`/`MOVSW`/`MOVSD`) | копирование элемента цепочки `ES:[EDI] ← DS:[ESI]` |
| `LODS` | загрузка элемента цепочки в `AL`/`AX`/`EAX` |
| `STOS` | запись элемента из аккумулятора в `ES:[EDI]` |
| `SCAS` | сравнение элемента цепочки с аккумулятором (поиск) |
| `CMPS` | сравнение двух элементов цепочек `DS:[ESI]` и `ES:[EDI]` |
Префиксы: `REP` — повторять, пока `ECX ≠ 0`; `REPE`/`REPZ` —
повторять, пока `ECX ≠ 0` **и** `ZF = 1`; `REPNE`/`REPNZ` — пока
`ECX ≠ 0` **и** `ZF = 0`. Направление просмотра задаётся флагом `DF`:
`CLD` (DF = 0, вперёд) или `STD` (DF = 1, назад).
> **Числовые варианты (12–16, 23–24):** числа в тексте нужно разбирать
> посимвольно — выполняйте `SCASB`/`LODSB`, выделяйте цифры (ASCII
> `'0'`..`'9'`), накапливайте цифры в число и анализируйте его.
**Проверка:** программа собирается и выдаёт правильный результат;
использованы минимум две цепочечные команды и префикс `REP*`.
### Задание 4. Вычислительный эксперимент и отладка — 1,5 балла
1. Прогнать программу на 3–5 контрольных строках:
| № | Контрольная строка | Назначение |
|---|--------------------|------------|
| 1 | пустая строка | проверка краевого случая |
| 2 | строка из одних пробелов | проверка обработки пробелов |
| 3 | строка с цифрами | вариант числового задания |
| 4 | строка со смешанным регистром | проверка ASCII |
| 5 | строка длиной около длины буфера | защита от переполнения |
2. Сверить результат, посчитанный вручную.
3. При расхождении — пройти ключевой фрагмент **пошагово** (OllyDbg
или встроенный отладчик) и зафиксировать в отчёте состояние
`EDI`/`ESI`/`ECX` и флагов `ZF`/`DF` после выполнения ключевой
команды.
**Проверка:** результаты совпадают с ручным расчётом; в отчёте
приведены значения регистров/флагов; пустая строка и строка пробелов
не приводят к сбою.
### Задание 5. Отчёт — 0,5 балла
Оформить отчёт по структуре из методических указаний:
Титульный лист.
Задание на лабораторную работу.
Введение.
1. Разработка алгоритма.
2. Разработка программы (листинг с комментариями).
3. Вычислительный эксперимент (контрольные строки, результаты, отладочная трассировка).
Выводы.
Список литературы.
---
## 3. Краткая теория
### 3.1. Цепочечные команды
Цепочечные команды (команды обработки строк символов) выполняют
действия над блоками памяти — последовательностями элементов
размером в байт (8 бит), слово (16 бит) или двойное слово (32 бита).
- **`MOVS dest,src`** — передаёт байт/слово/двойное слово из цепочки,
адресуемой `DS:[ESI]`, в цепочку `ES:[EDI]`. `EDI` и `ESI`
автоматически корректируются согласно флагу `DF`. Разновидности:
`MOVSB` (байт), `MOVSW` (слово), `MOVSD` (двойное слово).
- **`LODS src`** — загружает элемент цепочки в аккумулятор: байт → `AL`,
слово → `AX`, двойное слово → `EAX`; `ESI` корректируется.
Префикс `REP` не используется.
- **`STOS dest`** — команда, обратная `LODS`: передаёт элемент из
аккумулятора в цепочку и корректирует `EDI`.
- **`SCAS dest`** — сканирование цепочки: вычитает элемент цепочки из
аккумулятора (`AL`/`AX`/`EAX`) и модифицирует флаги. С префиксом
`REPNE` позволяет найти в цепочке нужный элемент.
- **`CMPS dest,src`** — сравнение цепочек: вычитает элемент цепочки
`dest` из соответствующего элемента `src`, модифицирует флаги;
`EDI` и `ESI` продвигаются к следующему элементу.
**Префикс `REP`** повторяет строковую операцию до обнуления `ECX`.
Разновидности: `REPZ` (`REPE`) — выполнять, пока `ZF = 1` (или пока
`ECX ≠ 0`); `REPNZ` (`REPNE`) — выполнять, пока `ZF = 0`. Цепочечная
команда без префикса выполняется один раз.
В Win32 программа пишется в одном большом («плоском») сегменте,
поэтому заботиться о сегментных регистрах `DS` и `ES` не нужно.
Флаг `DF` сбрасывается командой `CLD` и устанавливается `STD`.
### 3.2. Примеры типовых алгоритмов
**Пример 1. Копирование `STR1` в `STR2`:**
```asm
CLD
MOV ECX, N ; длина строки
LEA ESI, STR1
LEA EDI, STR2
REP MOVSB
```
**Пример 2. Сравнение двух строк:**
```asm
CLD
MOV ECX, N ; длина сравниваемых строк
LEA ESI, STR1
LEA EDI, STR2
REPE CMPSB
JNE NO_SAME
; ... строки равны
```
**Пример 3. Заполнение строки символом:**
```asm
CLD
MOV AL, 65 ; код символа
MOV ECX, 10 ; число символов
LEA EDI, STR2
REP STOSB
```
**Пример 4. Поиск в строке знаков '$' и замена их на '_':**
```asm
CLD
MOV AL, '$'
LEA EDI, STR2
MOV ECX, 20
LO:
REPNE SCASB ; поиск
JNZ DONE
MOV BYTE PTR [EDI-1], '_' ; замена
JMP LO
DONE:
```
**Пример 5. Поиск подстроки `STR1` (длина `N1`) в строке `STR2`
(длина `N2`), при `N2 > N1`:**
```asm
CLD
LEA EDI, STR2
MOV EAX, 0
MOV EDX, EDI ; EDX — адрес начала очередной попытки
LO:
MOV ECX, N1
LEA ESI, STR1
REPE CMPSB
JE FOUND
INC EDX
INC EAX
CMP EAX, N2-N1-1
JZ NO_FOUND
MOV EDI, EDX
JMP LO
NO_FOUND:
; ... строка не найдена
FOUND:
; ... строка найдена (начало — в EDX)
```
> Разбирая Пример 5, обратите внимание на роль регистра `EDX`:
> в нём хранится адрес символа в `STR2`, с которого начинается
> очередная попытка. При успехе именно в `EDX` находится начало
> найденной подстроки.
### 3.3. Окна, элементы управления и ввод строки
Чтобы создать окно в Win32, нужно:
1. получить дескриптор программы (`GetModuleHandle`);
2. зарегистрировать класс окна (`RegisterClassEx`), если не
используется предопределённый класс;
3. создать окно (`CreateWindowEx`);
4. показать окно (`ShowWindow`) и обновить его (`UpdateWindow`);
5. запустить цикл сообщений (`GetMessage`/`DispatchMessage`);
6. обрабатывать сообщения в оконной функции (`WndProc`).
Дочерние элементы управления (`button`, `edit`, список, флажок и т. д.)
создаются функцией `CreateWindowEx` с указанием предопределённого класса
и **дескриптора родителя** и **уникального ID**. Делается это обычно в
обработке `WM_CREATE`. Созданный элемент посылает родителю сообщения
`WM_COMMAND`: младшее слово `wParam` — ID элемента, старшее — код
уведомления (для кнопки — `BN_CLICKED`), `lParam` — дескриптор элемента.
Для сообщений **меню** `lParam == 0`.
Работа со строкой ввода:
```asm
SetWindowText proto hWnd:HWND, Str:PChar
GetWindowText proto hWnd:HWND, Str:PChar, MaxCount:DWORD
```
- `SetWindowText hwndEdit, ADDR TestString` — заполнить поле;
- `GetWindowText hwndEdit, ADDR buffer, 512` — прочитать текст
(в `EAX` возвращается число скопированных символов).
Родитель может слать команды элементу функцией `SendMessage`,
например эмулировать нажатие кнопки из пункта меню:
`invoke SendMessage, hWnd, WM_COMMAND, IDM_GETTEXT, 0`.
> Полный разбор (структура `WNDCLASSEX`, параметры `CreateWindowEx`,
> стили `WS_*`/`ES_*`/`BS_*`, примеры программ `PR2.ASM`, `PR8.ASM`)
> — в файле `Окна в MASM32.PDF`, разделы 9, 10, 14.
---
## 4. Содержание отчёта
**Титульный лист.**
**Задание на лабораторную работу** (номер варианта и его формулировка).
**Введение** (цель, краткие теоретические сведения).
1. **Разработка алгоритма** (блок-схема / пошаговое описание, распределение регистров).
2. **Разработка программы** (листинг с комментариями; пояснения по использованным цепочечным командам).
3. **Вычислительный эксперимент** (контрольные строки, ожидаемый и
полученный результат, фрагменты окна с введенной строкой и полученным в результате работы программы результатом).
**Выводы** (что подтвердилось, какие трудности, где применяются цепочечные команды).
**Список литературы.**
---
## 5. Варианты индивидуальных заданий (Приложение А)
Номер варианта выдаёт преподаватель.
### I. В диалоговом окне ввести строку, выполнить преобразование, вывести результат
1. Циклический сдвиг вправо на 1 символ.
2. Циклический сдвиг влево на 1 символ.
3. Выделить байт с наибольшим ASCII-кодом.
4. Выделить байт с наименьшим ASCII-кодом.
5. Произвести реверс байтов.
6. Поменять крайние символы местами.
7. Поменять средние символы местами.
8. Заменить чётные цифры символом `?`.
9. Заменить нечётные цифры символом `?`.
10. Убрать пробелы в тексте.
11. Заменить все символы `a` на символ, введённый с клавиатуры.
### II. В тексте определить количество чисел, у которых
12. Все цифры не совпадают.
13. Цифры образуют комбинацию «стрит» (напр.: 43576).
14. Три одинаковых цифры в числе (напр.: 36533).
15. Все цифры идут подряд (по возрастанию или убыванию).
16. Ни одной цифры подряд.
### III. В тексте найти
17. Количество гласных букв.
18. Количество согласных букв.
19. Количество слов с удвоенными согласными.
20. Количество слов с удвоенными гласными.
21. «Слова-перевёртыши» (напр.: кабак).
22. Слово с максимальным количеством одинаковых символов.
23. Количество чётных чисел.
24. Количество нечётных чисел.
### IV. Ввести 2 строки одинаковой длины, определить
25. Количество одинаковых символов.
26. Количество одинаковых слов.
27. Количество ошибок, если 1-я строка — шаблон, 2-я — проверяемый
текст.
---
## 6. Контрольные вопросы (допуск и защита)
1. Что такое цепочечная команда? Чем «цепочка» отличается от
«строки символов»?
2. Какую роль играют регистры `ESI`, `EDI`, `ECX` при выполнении
цепочечных команд?
3. Что делает команда `CLD` и как флаг `DF` влияет на изменение
`ESI`/`EDI`?
4. Чем отличаются префиксы `REP`, `REPE` (`REPZ`) и `REPNE` (`REPNZ`)?
5. Приведите определение команд `MOVS`, `LODS`, `STOS`, `SCAS`, `CMPS`.
6. Как в программе получить введённую пользователем строку? Где
хранится её длина?
7. Как различаются сообщения меню и элементов управления в
`WM_COMMAND`? Что хранится в `wParam` при `BN_CLICKED`?
8. Зачем при создании окна Win32 регистрировать класс окна перед
вызовом `CreateWindowEx`?
9. Что произойдёт, если не обработать `WM_DESTROY`?
10. В Примере 5 (поиск подстроки) зачем нужен регистр `EDX` и почему
после неудачного прохода `EDI` восстанавливается из `EDX`?
---
## 7. Оценивание
| Составляющая | Вес |
|--------------|-----|
| Задание 1 (окно: ввод/вывод) | 2,0 |
| Задание 2 (алгоритм варианта) | 2,0 |
| Задание 3 (программа: цепочечные команды) | 2,0 |
| Задание 4 (вычислительный эксперимент и отладка) | 1,5 |
| Задание 5 (отчёт) | 0,5 |
| Защита и допуск | 2,0 |
| **Максимум** | **10** |
Проходной балл — **6,0**. Допуск — устный опрос (раздел 6), не менее
3 правильных ответов из 5.
**Литература:**
1. Лекомцев П.В. Строковые операции в MASM32: методические указания
к выполнению лабораторной работы №3 по дисциплине «Основы
вычислительной техники». — Ижевск: ИжГТУ, 2012.
2. Яковлев А.В. Программирование на Ассемблере в Win32:
дополнительный лекционный материал. — Муром: Муромский институт
(филиал) ВлГУ, 2003.
3. Пирогов В.Ю. Assembler. Учебный курс. — М.: Молгачева С.В.,
Нолидж, 2001. — 848 с.
4. Пирогов В.Ю. Ассемблер для Windows. — 2-е изд., перераб. и доп. —
СПб.: БХВ-Петербург, 2003. — 656 с.
5. Юров В.И. Assembler. Учебник для вузов. — 2-е изд. — СПб.: Питер,
2004. — 637 с.