Files

22 KiB
Raw Permalink Blame History

Лабораторная работа №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:

CLD
MOV ECX, N            ; длина строки
LEA ESI, STR1
LEA EDI, STR2
REP MOVSB

Пример 2. Сравнение двух строк:

CLD
MOV ECX, N            ; длина сравниваемых строк
LEA ESI, STR1
LEA EDI, STR2
REPE CMPSB
JNE NO_SAME
; ... строки равны

Пример 3. Заполнение строки символом:

CLD
MOV AL, 65            ; код символа
MOV ECX, 10           ; число символов
LEA EDI, STR2
REP STOSB

Пример 4. Поиск в строке знаков '$' и замена их на '_':

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:

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.

Работа со строкой ввода:

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. В тексте определить количество чисел, у которых

  1. Все цифры не совпадают.
  2. Цифры образуют комбинацию «стрит» (напр.: 43576).
  3. Три одинаковых цифры в числе (напр.: 36533).
  4. Все цифры идут подряд (по возрастанию или убыванию).
  5. Ни одной цифры подряд.

III. В тексте найти

  1. Количество гласных букв.
  2. Количество согласных букв.
  3. Количество слов с удвоенными согласными.
  4. Количество слов с удвоенными гласными.
  5. «Слова-перевёртыши» (напр.: кабак).
  6. Слово с максимальным количеством одинаковых символов.
  7. Количество чётных чисел.
  8. Количество нечётных чисел.

IV. Ввести 2 строки одинаковой длины, определить

  1. Количество одинаковых символов.
  2. Количество одинаковых слов.
  3. Количество ошибок, если 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 с.