Загрузка данных


;файл prog.asm
.586P
;плоская модель памяти
.MODEL FLAT, stdcall
;константы
;сообщение приходит при закрытии окна
WM_CLOSE      equ 10h
WM_INITDIALOG equ 110h
WM_COMMAND    equ 111h
WM_TIMER      equ 113h
;прототипы внешних процедур
EXTERN ReleaseDC@8:NEAR
EXTERN GetDC@4:NEAR
EXTERN TextOutA@20:NEAR
EXTERN MessageBoxA@16:NEAR
EXTERN ExitProcess@4:NEAR
EXTERN GetModuleHandleA@4:NEAR
EXTERN DialogBoxParamA@20:NEAR
EXTERN EndDialog@8:NEAR
EXTERN SendMessageA@16:NEAR
EXTERN SetTimer@16:NEAR
EXTERN KillTimer@8:NEAR

;структура сообщения
MSGSTRUCT STRUC
    MSHWND    DD ?
    MSMESSAGE DD ?
    MSWPARAM  DD ?
    MSLPARAM  DD ?
    MSTIME    DD ?
    MSPT      DD ?
MSGSTRUCT ENDS
;директивы компоновщику для подключения библиотек
;для компоновщика LINK.EXE
includelib f:\masm32\lib\user32.lib
includelib f:\masm32\lib\kernel32.lib
includelib f:\masm32\lib\gdi32.lib
;--------------------------------
;сегмент данных
_DATA SEGMENT
    MSG   MSGSTRUCT <>
    HINST DD 0 ;дескриптор приложения
    PA    DB "DIAL1",0
    COUNT DD 0
    TEXT  DB 0
    CAP   DB 'Сообщение',0
    MES   DB 'Выход по таймеру',0
_DATA ENDS
;сегмент кода
_TEXT SEGMENT
START:
;получить дескриптор приложения
    PUSH 0
    CALL GetModuleHandleA@4
    MOV HINST, EAX
;--------------------------------
    PUSH 0
    PUSH OFFSET WNDPROC
    PUSH 0
    PUSH OFFSET PA
    PUSH HINST
    CALL DialogBoxParamA@20
    CMP EAX,-1
    JNE KOL
KOL:
;--------------------------------
    PUSH 0
    CALL ExitProcess@4

;--------------------------------
;процедура окна
;расположение параметров в стеке
; [EBP+014H] ;LPARAM
; [EBP+10H]  ;WAPARAM
; [EBP+0CH]  ;MES
; [EBP+8]    ;HWND
WNDPROC PROC
    PUSH EBP
    MOV EBP,ESP
    PUSH EBX
    PUSH ESI
    PUSH EDI
;--------------------------------
    CMP DWORD PTR [EBP+0CH],WM_CLOSE
    JNE L1
;здесь реакция на закрытие окна
L3:
;удалить таймер
    PUSH 1;идентификатор таймера
    PUSH DWORD PTR [EBP+08H]
    CALL KillTimer@8
;закрыть диалог
    PUSH 0
    PUSH DWORD PTR [EBP+08H]
    CALL EndDialog@8
    JMP FINISH
L1:
    CMP DWORD PTR [EBP+0CH],WM_INITDIALOG
    JNE L5
;здесь начальная инициализация
;установить таймер
    PUSH 0;параметр = NULL
    PUSH 1000;интервал 1 с.
    PUSH 1;идентификатор таймера
    PUSH DWORD PTR [EBP+08H]
    CALL SetTimer@16
    JMP FINISH
L5:
    CMP DWORD PTR [EBP+0CH],WM_COMMAND
    JNE L2
;кнопка выхода?
    CMP WORD PTR [EBP+10H],5
    JNE FINISH
    JMP L3

L2:
    CMP DWORD PTR [EBP+0CH],WM_TIMER
    JNE FINISH
;не пора ли заканчивать?
    CMP COUNT,9
;выход без предупреждения
    JA L3
;выход через сообщение
    JE L4
;пришло сообщение таймера
;подготовить текст
    MOV EAX,COUNT
    ADD EAX,49
    MOV TEXT,AL
;получить контекст
    PUSH DWORD PTR [EBP+08H]
    CALL GetDC@4
;запомнить контекст
    PUSH EAX
;вывести значение счетчика
    PUSH 1
    PUSH OFFSET TEXT
    PUSH 10
    PUSH 10
    PUSH EAX
    CALL TextOutA@20
;удалить контекст
    POP EAX
    PUSH EAX
    PUSH DWORD PTR [EBP+08H]
    CALL ReleaseDC@8
;увеличить счетчик
    INC COUNT
    JMP FINISH
L4:
    INC COUNT
;сообщение о выходе по таймеру
    PUSH 0
    PUSH OFFSET CAP
    PUSH OFFSET MES
    PUSH DWORD PTR [EBP+08H] ;дескриптор окна
    CALL MessageBoxA@16
    JMP L3

FINISH:
    POP EDI
    POP ESI
    POP EBX
    POP EBP
    MOV EAX,0
    RET 16
WNDPROC ENDP
;--------------------------------
_TEXT ENDS
END START