;fenix.asm, внешний вид арифмометра с обработкой кнопок и конвертацией типов
.586
.model flat, stdcall
include сonst.inc
.data
include data.inc
.code
main:
push 0
call GetModuleHandleA@4
mov [hInst],eax
winmain proc
mov [wc.CLSSTYLE],STYLE
mov [wc.CLWNDPROC],offset winproc
mov [wc.CLSCBCLSEX],0
mov [wc.CLSCBWNDEX],0
mov eax,[hInst]
mov [wc.CLSHINST],eax
push IDI_APPLICATION
push 0
call LoadIconA@8
mov [wc.CLSHICON],eax
push IDC_ARROW
push 0
call LoadCursorA@8
mov [wc.CLSHCURSOR],eax
mov [wc.CLBKGROUND],18
mov DWORD ptr [wc.CLMENNAME],0
mov DWORD ptr [wc.CLNAME],offset CLASSNAME
push offset wc
call RegisterClassA@4
;окно арифмометра:
push 0
push [hInst]
push 0
push 0
push 225 ;y-высота окна
push 215 ;x-ширина окна
push 200
push 200
push WS_OVERLAPPEDWINDOW
push offset titleName
push offset className
push 0
call CreateWindowExA@48
cmp eax,0
jz _err
mov [hWnd],eax
push SW_SHOWNORMAL
push [hWnd]
call ShowWindow@8
push [hWnd]
call UpdateWindow@4
msg_loop:
push 0
push 0
push 0
push offset msg
call GetMessageA@16
cmp eax,0
je end_loop
push offset msg
call TranslateMessage@4
push offset msg
call DispatchMessageA@4
jmp msg_loop
end_loop:
push [msg.MSWPARAM]
call ExitProcess@4
_err:
jmp end_loop
winmain endp ;создали окно арифмометра
winproc proc ;процедура окна
push ebp
mov ebp,esp
push ebx
push esi
push edi
cmp dword ptr [ebp+0Ch],WM_CREATE
je wmcreate
cmp dword ptr [ebp+0Ch],WM_COMMAND
je wmcommand
cmp dword ptr [ebp+0Ch],WM_DESTROY
je wmdestroy
jmp defwndproc
wmcreate: ;начинаем обработку WM_CREATE
;-------------------------- C (y=)----------------------------------
push 0
push [hInst]
push 0
push [ebp+08h]
push 150 ;высота
push 30 ;ширина
push 40 ;y-сверху
push 10 ;x-слева
push STYLBUT
push offset butC
push offset clsBut
push 0
call CreateWindowExA@48
mov hbutC,eax
mov eax,0
;-------------------------- 1 (y=40)----------------------------------
push 0
push [hInst]
push 0
push [ebp+08h]
push 30
push 30
push 40
push 50
push STYLBUT
push offset but1
push offset clsBut
push 0
call CreateWindowExA@48
mov hbut1,eax
mov eax,0
;-------------------------- 2 (y=40)----------------------------------
push 0
push [hInst]
push 0
push [ebp+08h]
push 30
push 30
push 40
push 90
push STYLBUT
push offset but2
push offset clsBut
push 0
call CreateWindowExA@48
mov hbut2,eax
mov eax,0
;-------------------------- 3 (y=40)----------------------------------
push 0
push [hInst]
push 0
push [ebp+08h]
push 30
push 30
push 40
push 130
push STYLBUT
push offset but3
push offset clsBut
push 0
call CreateWindowExA@48
mov hbut3,eax
mov eax,0
;-------------------------- 4 (y=80)----------------------------------
push 0
push [hInst]
push 0
push [ebp+08h]
push 30
push 30
push 80
push 50
push STYLBUT
push offset but4
push offset clsBut
push 0
call CreateWindowExA@48
mov hbut4,eax
mov eax,0
;----------------------------------5(y=80)------------------------------------
push 0
push [hInst]
push 0
push [ebp+08h]
push 30
push 30
push 80
push 90
push STYLBUT
push offset but5
push offset clsBut
push 0
call CreateWindowExA@48
mov hbut5,eax
mov eax,0
;-------------------------- 6 (y=)----------------------------------
push 0
push [hInst]
push 0
push [ebp+08h]
push 30
push 30
push 80
push 130
push STYLBUT
push offset but6
push offset clsBut
push 0
call CreateWindowExA@48
mov hbut6,eax
mov eax,0
;------------------------------------7(y=50)-----------------------------------
push 0
push [hInst]
push 0
push [ebp+08h]
push 30
push 30
push 120
push 50
push STYLBUT
push offset but7
push offset clsBut
push 0
call CreateWindowExA@48
mov hbut7,eax
mov eax,0
;-------------------------- 8 (y=80)----------------------------------
push 0
push [hInst]
push 0
push [ebp+08h]
push 30
push 30
push 120
push 90
push STYLBUT
push offset but8
push offset clsBut
push 0
call CreateWindowExA@48
mov hbut8,eax
mov eax,0
;-------------------------- 9 (y=120)----------------------------------
push 0
push [hInst]
push 0
push [ebp+08h]
push 30
push 30
push 120
push 130
push STYLBUT
push offset but9
push offset clsBut
push 0
call CreateWindowExA@48
mov hbut9,eax
mov eax,0
;------------------------------------0(y=50)-----------------------------------
push 0
push [hInst]
push 0
push [ebp+08h]
push 30
push 30
push 160
push 50
push STYLBUT
push offset but0
push offset clsBut
push 0
call CreateWindowExA@48
mov hbut0,eax
mov eax,0
;------------------------------------+(y=40)-----------------------------------
push 0
push [hInst]
push 0
push [ebp+08h]
push 30
push 30
push 40
push 170
push STYLBUT
push offset butS
push offset clsBut
push 0
call CreateWindowExA@48
mov hbutS,eax
mov eax,0
;----------------------------------- - (y=80)-----------------------------------
push 0
push [hInst]
push 0
push [ebp+08h]
push 30
push 30
push 80
push 170
push STYLBUT
push offset butM
push offset clsBut
push 0
call CreateWindowExA@48
mov hbutM,eax
mov eax,0
;----------------------------------- * (y=120)-----------------------------------
push 0
push [hInst]
push 0
push [ebp+08h]
push 30
push 30
push 120
push 170
push STYLBUT
push offset butU
push offset clsBut
push 0
call CreateWindowExA@48
mov hbutU,eax
mov eax,0
;----------------------------------- : (y=160)-----------------------------------
push 0
push [hInst]
push 0
push [ebp+08h]
push 30
push 30
push 160
push 170
push STYLBUT
push offset butD
push offset clsBut
push 0
call CreateWindowExA@48
mov hbutD,eax
mov eax,0
;------------------------------------=(y=160)-----------------------------------
push 0
push [hInst]
push 0
push [ebp+08h]
push 30
push 70
push 160
push 90
push STYLBUT
push offset butI
push offset clsBut
push 0
call CreateWindowExA@48
mov hbutI,eax
mov eax,0
;----------------------окно редактирования----------------------------
push 0
push [hInst]
push 0
push [ebp+08h]
push 20
push 190
push 10
push 10
push STYLEDT
push offset Edt
push offset clsEdt
push 0
call CreateWindowExA@48
mov hedt,eax
jmp exit ;закончили обработку WM_CREATE - это была графика
wmcommand: ;начинаем обработку WM_COMMAND - на что нажали
mov eax,hbut1 ;хэндл "1"
cmp [ebp+14h],eax ;нажали "1"?
je nabor ;переходим сюда
mov eax,hbut2 ;и т.д.
cmp [ebp+14h],eax
je nabor
mov eax,hbut3
cmp [ebp+14h],eax
je nabor
mov eax,hbut4
cmp [ebp+14h],eax
je nabor
mov eax,hbut5
cmp [ebp+14h],eax
je nabor
mov eax,hbut6
cmp [ebp+14h],eax
je nabor
mov eax,hbut7
cmp [ebp+14h],eax
je nabor
mov eax,hbut8
cmp [ebp+14h],eax
je nabor
mov eax,hbut9
cmp [ebp+14h],eax
je nabor
mov eax,hbut0
cmp [ebp+14h],eax
je nabor
mov eax,hbutS
cmp [ebp+14h],eax
je plus
mov eax,hbutM
cmp [ebp+14h],eax
je minus
mov eax,hbutU
cmp [ebp+14h],eax
je umno
mov eax,hbutD
cmp [ebp+14h],eax
je deli
mov eax,hbutC
cmp [ebp+14h],eax
je clear
mov eax,hbutI
cmp [ebp+14h],eax
je itog
jmp defwndproc ;возвращаемся в процедуру
;всё, что ниже, обрабатывается только после непосредственного обращения
nabor: ;обработка кнопок полного цикла
push 10
push offset buf ;получаем содержимое дисплея
push [hedt]
call GetWindowTextA@12
add eax,offset buf ;добавляем его в еах
push 10
push eax ;туда-же добавляем
push [EBP+14h] ;символ нажатой кнопки
call GetWindowTextA@12
call settext
jmp exit
plus: ;жмём "+"...одна из 4-х кнопок операций, начало цикла
call plu
jmp exit
minus:
call min
jmp exit
umno:
call umn
jmp exit
deli:
call del
jmp exit
clear: ;кнопка полного цикла
call clproc
jmp exit
itog: ;набрали 2-е число, нажимаем "="
mov edi,select
cmp edi,hbutS
je plus_ex
cmp edi,hbutM
je minus_ex
cmp edi,hbutU
je umno_ex
cmp edi,hbutD
je deli_ex
plus_ex:
call pluex
jmp exit
minus_ex:
call minex
jmp exit
umno_ex:
call umnex
jmp exit
deli_ex:
call delex
jmp exit
exit: ;заканчиваем работу программы
xor eax,eax
xor ebx,ebx
jmp finish
wmdestroy: ;обрабатываем WM_DESTROY, если...
push 0
call PostQuitMessage@4
defwndproc: ;обрабатываем msg-и
push [ebp+14h] ;lParam
push [ebp+10h] ;wParam
push [ebp+0Ch] ;Msg
push [ebp+08h] ;hWnd
call DefWindowProcA@16
finish:
pop edi
pop esi
pop ebx
pop ebp
ret 16
winproc endp
--------------------------- вспомогательные процедуры: --------------------
clproc proc ;процедура очистки дисплея
push offset Edt
push [hedt]
call SetWindowTextA@8
ret
clproc endp
settext proc ;процедура вывода результата на дисплей
push offset buf
push [hedt]
call SetWindowTextA@8
ret
settext endp
;--------------------- арифметика ------------------------------------------------
plu proc
push esi
push ebx
mov esi,hbutS ;запоминаем...
mov sel,esi ;...тип операции (аналог --> select = "+")
call asc2bin ;преобразуем 1-е ASCII-число
mov ebx,bin
mov bin1,ebx ;bin1 <-- 1-e дв.число
pop ebx
pop esi
call clproc ;очищаем дисплей
ret
plu endp
pluex proc
call clproc ;очищаем дисплей
call asc2bin ;преобразуем 2-е ASCII-число
call add_32 ;процедура сложения
call bin2asc ;преобразуем итог в ASCII-число
call settext ;добавляем итог на дисплей
ret
pluex endp
add_32 proc
push eax
mov eax,bin1
add eax,bin
mov dword ptr res,eax
mov eax,bin1+4
adc eax,bin+4
mov dword ptr res+4,eax
pop eax
ret
add_32 endp
min proc
push ebx
push esi
mov esi,hbutM
mov sel,esi
call asc2bin
mov ebx,bin
mov bin1,ebx
call clproc
pop esi
pop ebx
ret
min endp
minex proc
call clproc
call asc2bin
call sub_32
call bin2asc
call settext
ret
minex endp
sub_32 proc
push eax
mov eax,bin1
sub eax,bin
mov dword ptr res,eax
mov eax,bin1+4
sbb eax,bin+4
mov dword ptr res+4,eax
pop eax
ret
sub_32 endp
umn proc
push ebx
push esi
mov esi,hbutU
mov sel,esi
call asc2bin
mov ebx,bin
mov bin1,ebx
call clproc
pop esi
pop ebx
ret
umn endp
umnex proc
call clproc
call asc2bin
call mul_32
call bin2asc
call settext
ret
umnex endp
mul_32 proc
pushad
mov eax,bin1
mov ebx,eax
mul bin
mov dword ptr res,eax
mov ecx,edx
mov eax,ebx
mul bin+4
add eax,ecx
adc edx,0
mov ebx,eax
mov ecx,edx
mov eax,bin1+4
mul bin
add eax,ebx
mov dword ptr res+4,eax
adc ecx,edx
mov eax,bin1+4
mul bin+4
add eax,ecx
adc edx,0
mov dword ptr res+8,eax
mov dword ptr res+12,edx
ret
popad
ret
mul_32 endp
del proc
push ebx
push esi
mov esi,hbutD
mov sel,esi
call asc2bin
mov ebx,bin
mov bin1,ebx
call clproc
pop esi
pop ebx
ret
del endp
delex proc
call clproc
call asc2bin
call div_32
call bin2asc
call settext
ret
delex endp
div_32 proc
pushad
mov ebx,bin
mov eax,bin1
mov edx,bin1+4
div ebx
mov dword ptr res,eax
mov ost,edx
popad
ret
div_32 endp
;-------------------- конвертация типов ------------------------------------
asc2bin proc ;(((eax*10)+edx)*10+edx)*...
pushad
xor ebx,ebx ;обнулимся...
xor eax,eax
mov edi,ten ;10 - основание системы счисления
lea ecx,buf ;адрес 1-го ASCII-символа
cycl:
mov bl,[esi] ;выберем ASCII-символ
or bl,bl ;нечего выбирать?
jz fin ;на выход
and bl,0Fh ;преобразуем ASCII-символ
mul edi ;edx:eax = eax*10
add eax,ebx ;промежуточная сумма
inc ecx ;к следующему символу
jc exit ;если CF=1
jmp cycl ;повторим
fin:
mov bin,eax ;сохраним дв.число
popad
exit: ;для возможной обработки CF
ret
asc2bin endp
bin2asc proc
pushad
mov eax,dword ptr res
lea edi,buf
mov ebx,ten ;основание системы счисления
xor ecx,ecx ;обнуляем счётчик
conv:
xor edx,edx ;обнулимся...
div ebx ;eax=частн(edx:eax/10), edx=ост(edx:eax/10)
add dl,30h ;cформируем ASCII-символ
push edx ;сохраним для разворота
inc ecx ;ECX+1 --> rev
test eax,eax ;преобразование закончено?
jnz conv
rev:
pop edx
mov [edi],dl ;занесём ASCII-символ в буфер
inc edi ;смещаемся
loop rev
mov byte ptr [edi],0
exit:
popad
ret
bin2asc endp
end main
↑ К началу странички
рис.9