ai: студенческая копия ЛР №3 «Строковые операции в MASM32» из РПД (окно Win32, ввод строки, цепочечные команды)
This commit is contained in:
@@ -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
|
||||
@@ -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
|
||||
; ============================================================================
|
||||
Reference in New Issue
Block a user