;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