commit b38aaa434bc9eed08bbfb5dfbd561281fea8c1fb Author: mss Date: Thu Nov 5 19:48:11 2026 +0400 ai: студенческая копия ЛР №3 «Строковые операции в MASM32» из РПД (окно Win32, ввод строки, цепочечные команды) diff --git a/README.md b/README.md new file mode 100644 index 0000000..a4a4fae --- /dev/null +++ b/README.md @@ -0,0 +1,104 @@ +# ОВТ3 — Строковые операции в MASM32 + +Репозиторий студента для одной лабораторной работы. + +**Дисциплина:** Основы вычислительной техники и операционные системы +автоматизированных технологических комплексов (Б1.В.01) +**Специальность:** 15.03.06 «Мехатроника и робототехника» +**Семестр:** 3 · **Объём:** 4 часа + +Название репозитория расшифровывается так: + +| Часть | Значение | +|---|---| +| `ovt` | ОВТ — основы вычислительной техники | +| `3` | третья лабораторная работа | +| `masm` | среда MASM32, язык Assembler | +| `strings` | строковые (цепочечные) операции | + +> Черновик. Требует проверки преподавателем перед выдачей студентам. + +--- + +## О чём работа + +Вы пишете GUI-приложение на языке Assembler для Win32 в среде MASM32: +в диалоговом окне Windows вводится строка, над ней выполняется +преобразование по индивидуальному варианту (Приложение А), результат +выводится обратно. В основе обработки — **цепочечные команды** +`MOVS`, `LODS`, `STOS`, `SCAS`, `CMPS` и префиксы `REP`/`REPE`/`REPNE`. + +Полное задание, теория, 27 вариантов и вопросы допуска/защиты — +в **[task.md](task.md)**. + +--- + +## Что в репозитории + +``` +ovt3-masm-strings/ +├── README.md ← этот файл +├── task.md ← задание, теория, варианты, вопросы +├── stub/ ← заготовки (выдаёт преподаватель по лестнице) +│ ├── 01-window.asm ← каркас окна: edit + button, WM_CREATE/WM_COMMAND +│ └── 02-strings.asm ← каркас обработки строки (TODO по варианту) +└── print/ ← брошюра задания (DOCX) + └── methodical-lab3-strokovye-operatsii-student.docx +``` + +### Что в заготовках + +| Файл | Что внутри | Что доделать | +|---|---|---| +| `stub/01-window.asm` | регистрация класса окна, создание главного окна, поле ввода (`edit`), кнопка (`button`), обработка `WM_CREATE`/`WM_COMMAND`/`WM_DESTROY` | вписать обработку строки в ветке `BN_CLICKED` | +| `stub/02-strings.asm` | примеры типовых приёмов (копирование, сравнение, поиск) и каркас `process_string` с `TODO` | реализовать алгоритм варианта цепочечными командами | + +> **Важно:** заготовки — это стартовая точка, а не решение. Логику +> варианта (задание 3) пишете вы сами. + +--- + +## Быстрый старт + +1. **Установить MASM32** (пакет `masm32` — редактор QEditor, ассемблер + `ml`, компоновщик `link`). Ассемблер должен лежать в `\masm32` — + в исходниках пути вида `\masm32\include\windows.inc`. +2. **Собрать окно** из заготовки `stub/01-window.asm`: + + ```bat + ml /c /coff 01-window.asm + link /subsystem:windows 01-window.obj + ``` + + Запустить `01-window.exe` — должно появиться окно с полем ввода и + кнопкой (кнопка пока выводит введённую строку без изменений). +3. **Реализовать вариант** в `stub/02-strings.asm` (процедура + `process_string`) и подключить её к обработчику кнопки. +4. **Проверить** на контрольных строках (пустая строка, строка из + пробелов, строка с цифрами) и, при необходимости, пройти ключевой + фрагмент пошагово в **OllyDbg**. +5. **Оформить отчёт** по структуре из `task.md`, раздел 4. + +Или собрать через QEditor: открыть файл и «Build → Build all». + +--- + +## Полезные ссылки + +- `task.md` — задание, теория цепочечных команд, 27 вариантов, + контрольные вопросы, оценивание. +- Дополнительный материал по окнам Win32 (`Окна в MASM32.PDF`, + разделы 9, 10, 14) — на диске с методическими материалами или у + преподавателя. + +--- + +## Порядок сдачи + +1. Реализовать и собрать программу (задания 1–3). +2. Провести вычислительный эксперимент (задание 4). +3. Оформить отчёт (задание 5). +4. Ответить на контрольные вопросы (`task.md`, раздел 6). + +Баллы по заданиям — в `task.md`, раздел 7. +Зачёт при **6 и более** баллах из 10. diff --git a/print/methodical-lab3-strokovye-operatsii-student.docx b/print/methodical-lab3-strokovye-operatsii-student.docx new file mode 100644 index 0000000..b1b4eb6 Binary files /dev/null and b/print/methodical-lab3-strokovye-operatsii-student.docx differ diff --git a/stub/01-window.asm b/stub/01-window.asm new file mode 100644 index 0000000..7150a73 --- /dev/null +++ b/stub/01-window.asm @@ -0,0 +1,149 @@ +; ============================================================================ +; 01-window.asm — каркас GUI-приложения Win32 на MASM32 +; Лабораторная №3 «Строковые операции в MASM32», Задание 1 +; ---------------------------------------------------------------------------- +; Это ЗАГОТОВКА окна: регистрация класса, создание главного окна, поле ввода +; (edit) и кнопка (button), обработка WM_CREATE / WM_COMMAND / WM_DESTROY. +; Логика обработки строки (по варианту) — в файле 02-strings.asm. +; +; Сборка в MASM32: ml /c /coff 01-window.asm +; link /subsystem:windows 01-window.obj +; ============================================================================ +; ФИО: ____________________ Вариант: ____ Группа: ______ +; Дата: ____.__.____ Выдано: (лаботряс) +; ============================================================================ + +.386 +.model flat, stdcall +option casemap:none + +WinMain proto :DWORD, :DWORD, :DWORD, :DWORD + +include \masm32\include\windows.inc +include \masm32\include\user32.inc +include \masm32\include\kernel32.inc + +includelib \masm32\lib\user32.lib +includelib \masm32\lib\kernel32.lib + +; ---------------------------------------------------------------- .data +.data +ClassName db "SimpleWinClass",0 +AppName db "Строковые операции (МАСМ32)",0 +ButtonClassName db "button",0 +ButtonText db "Обработать",0 +EditClassName db "edit",0 + +; ---------------------------------------------------------------- .data? +.data? +hInstance HINSTANCE ? +CommandLine LPSTR ? +hwndEdit HWND ? +hwndButton HWND ? +buffer db 512 dup(?) ; буфер ввода/вывода строки +sizestr dd ? ; длина строки (возвращает GetWindowText) + +; ---------------------------------------------------------------- .const +.const +ButtonID equ 1 +EditID equ 2 + +; ---------------------------------------------------------------- .code +.code +start: + invoke GetModuleHandle, NULL + mov hInstance, eax + invoke GetCommandLine + mov CommandLine, eax + invoke WinMain, hInstance, NULL, CommandLine, SW_SHOWDEFAULT + invoke ExitProcess, eax + +; ---------------------------------------------------- WinMain: окно +WinMain proc hInst:HINSTANCE, hPrevInst:HINSTANCE, CmdLine:LPSTR, CmdShow:DWORD + LOCAL wc:WNDCLASSEX + LOCAL msg:MSG + LOCAL hwnd:HWND + + mov wc.cbSize, SIZEOF WNDCLASSEX + mov wc.style, CS_HREDRAW or CS_VREDRAW + mov wc.lpfnWndProc, OFFSET WndProc + mov wc.cbClsExtra, NULL + mov wc.cbWndExtra, NULL + push hInst + pop wc.hInstance + mov wc.hbrBackground, COLOR_BTNFACE+1 + mov wc.lpszMenuName, NULL + mov wc.lpszClassName, OFFSET ClassName + invoke LoadIcon, NULL, IDI_APPLICATION + mov wc.hIcon, eax + mov wc.hIconSm, eax + invoke LoadCursor, NULL, IDC_ARROW + mov wc.hCursor, eax + invoke RegisterClassEx, addr wc + + invoke CreateWindowEx, WS_EX_CLIENTEDGE, ADDR ClassName, ADDR AppName, \ + WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, 460, 260, \ + NULL, NULL, hInst, NULL + mov hwnd, eax + invoke ShowWindow, hwnd, SW_SHOWNORMAL + invoke UpdateWindow, hwnd + + .WHILE TRUE + invoke GetMessage, ADDR msg, NULL, 0, 0 + .BREAK .IF (!eax) + invoke TranslateMessage, ADDR msg + invoke DispatchMessage, ADDR msg + .ENDW + mov eax, msg.wParam + ret +WinMain endp + +; ---------------------------------------------------- WndProc: сообщения +WndProc proc hWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM + .IF uMsg == WM_DESTROY + invoke PostQuitMessage, NULL + + .ELSEIF uMsg == WM_CREATE + ; ---- поле ввода (edit) ---- + invoke CreateWindowEx, WS_EX_CLIENTEDGE, ADDR EditClassName, NULL, \ + WS_CHILD or WS_VISIBLE or WS_BORDER or ES_LEFT or ES_AUTOHSCROLL, \ + 20, 20, 400, 24, hWnd, EditID, hInstance, NULL + mov hwndEdit, eax + invoke SetFocus, hwndEdit + ; ---- кнопка (button) ---- + invoke CreateWindowEx, NULL, ADDR ButtonClassName, ADDR ButtonText, \ + WS_CHILD or WS_VISIBLE or BS_DEFPUSHBUTTON, \ + 140, 70, 160, 28, hWnd, ButtonID, hInstance, NULL + mov hwndButton, eax + + .ELSEIF uMsg == WM_COMMAND + mov eax, wParam + .IF lParam == 0 + ; сообщения меню (меню в каркасе нет) + .ELSE + ; сообщения элементов управления: + ; ax = ID элемента, старшее слово = код уведомления + .IF ax == ButtonID + shr eax, 16 + .IF ax == BN_CLICKED + ; ---- TODO: получить строку и обработать её ---- + invoke GetWindowText, hwndEdit, ADDR buffer, 512 + mov sizestr, eax ; длина строки + + ; TODO(вариант): здесь вызвать обработку buffer + ; (см. 02-strings.asm) и записать результат обратно. + ; Пока — эхо-вывод для проверки GUI: + invoke SetWindowText, hwndEdit, ADDR buffer + .ENDIF + .ENDIF + .ENDIF + + .ELSE + invoke DefWindowProc, hWnd, uMsg, wParam, lParam + ret + .ENDIF + xor eax, eax + ret +WndProc endp + +end start diff --git a/stub/02-strings.asm b/stub/02-strings.asm new file mode 100644 index 0000000..07824be --- /dev/null +++ b/stub/02-strings.asm @@ -0,0 +1,83 @@ +; ============================================================================ +; 02-strings.asm — каркас обработки строки цепочечными командами +; Лабораторная №3 «Строковые операции в MASM32», Задания 2–3 +; ---------------------------------------------------------------------------- +; Это ЗАГОТОВКА: показан типовой проход по строке цепочечными командами, +; но ЛОГИКА ВАРИАНТА не реализована (см. TODO). Впиши свой алгоритм. +; +; Регистры цепочечных команд: +; ESI — источник (DS:[ESI]), EDI — приёмник (ES:[EDI]), ECX — счётчик. +; Направление задаёт флаг DF: CLD — вперёд, STD — назад. +; Команды: MOVS (копирование), LODS (в AL/AX/EAX), STOS (запись), +; SCAS (поиск), CMPS (сравнение). Префиксы: REP, REPE, REPNE. +; ============================================================================ +; ФИО: ____________________ Вариант: ____ Группа: ______ +; Дата: ____.__.____ Выдано: (лаботряс) +; ============================================================================ + +; ------------------------------------------------- пример 1: копирование +; Скопировать строку из buffer в buffer2 (N — длина) +; CLD +; MOV ECX, N +; LEA ESI, buffer +; LEA EDI, buffer2 +; REP MOVSB + +; ------------------------------------------------- пример 2: сравнение строк +; Равны ли buffer и buffer2? +; CLD +; MOV ECX, N +; LEA ESI, buffer +; LEA EDI, buffer2 +; REPE CMPSB +; JNE NO_SAME +; ; ... равны +; NO_SAME: +; ; ... не равны + +; ------------------------------------------------- пример 3: поиск символа +; Заменить все '$' на '_' (ECX — длина строки) +; CLD +; MOV AL, '$' +; LEA EDI, buffer +; MOV ECX, N +; LO: +; REPNE SCASB +; JNZ DONE +; MOV BYTE PTR [EDI-1], '_' +; JMP LO +; DONE: + +; ============================================================================ +; TODO(вариант): реализуй обработку в процедуре process_string. +; Вход: buffer — строка (ASCIIZ), sizestr — её длина без терминатора 0 +; Выход: buffer — результат (переписать на месте) +; Обязательно: минимум ДВЕ цепочечные команды и префикс REP*/CLD. +; ============================================================================ +.code +process_string proc + ; ---- защита от пустой строки ---- + mov ecx, sizestr + test ecx, ecx + jz done ; пустая строка — выходим + + CLD + ; ------------------------------------------------------------------ + ; TODO 1: настроить регистры (LEA ESI/EDI, MOV ECX, ...) + ; ------------------------------------------------------------------ + ; TODO 2: выполнить обработку цепочечными командами МОВS/LODS/STOS/ + ; SCAS/CMPS + REP*/REPE/REPNE согласно варианту + ; ------------------------------------------------------------------ + ; TODO 3: уложить результат в buffer (можно на месте) + +done: + ret +process_string endp +; ============================================================================ +; TODO(интеграция): вызвать process_string из обработчика кнопки в +; 01-window.asm (в ветке BN_CLICKED), например: +; invoke GetWindowText, hwndEdit, ADDR buffer, 512 +; mov sizestr, eax +; call process_string +; invoke SetWindowText, hwndEdit, ADDR buffer +; ============================================================================ diff --git a/task.md b/task.md new file mode 100644 index 0000000..9974fa6 --- /dev/null +++ b/task.md @@ -0,0 +1,411 @@ +# Лабораторная работа №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 с.