ai: студенческая копия ЛР №3 «Строковые операции в MASM32» из РПД (окно Win32, ввод строки, цепочечные команды)

This commit is contained in:
mss
2026-11-05 19:48:11 +04:00
commit b38aaa434b
5 changed files with 747 additions and 0 deletions
+149
View File
@@ -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
+83
View File
@@ -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
; ============================================================================