19.07.2019, 16:15 [+3 UTC]
в нашей команде: 3 750 чел. | участники онлайн: 2 (рекорд: 21)

:: РЕГИСТРАЦИЯ

задать вопрос

все разделы

правила

новости

участники

доска почёта

форум

блоги

поиск

статистика

наш журнал

наши встречи

наша галерея

отзывы о нас

поддержка

руководство

Версия системы:
7.77 (31.05.2019)
JS-v.1.34 | CSS-v.3.35

Общие новости:
28.04.2019, 09:13

Форум:
18.07.2019, 12:26

Последний вопрос:
19.07.2019, 11:17
Всего: 149942

Последний ответ:
19.07.2019, 12:46
Всего: 258709

Последняя рассылка:
17.07.2019, 22:15

Писем в очереди:
0

Мы в соцсетях:

Наша кнопка:

RFpro.ru - здесь вам помогут!

Отзывы о нас:
20.03.2010, 19:58 »
Розанкова Наталья Юрьевна
Боже спасибо большое Shvetski!!!!!! Вы мне очень помогли, спасибо!!!!!!!!!! [вопрос № 177366, ответ № 260259]
07.03.2012, 11:06 »
Александр
близко к тому что я хотел и имелись пояснения [вопрос № 185553, ответ № 270156]
30.04.2010, 11:05 »
Botsman
Спасибо. Оперативно и обоснованно! [вопрос № 178113, ответ № 261119]

РАЗДЕЛ • Assembler

Создание программ на языке Assembler.

[администратор рассылки: Лысков Игорь Витальевич (Старший модератор)]

Лучшие эксперты в этом разделе

Зенченко Константин Николаевич
Статус: Старший модератор
Рейтинг: 197
Коцюрбенко Алексей Владимирович
Статус: Модератор
Рейтинг: 142
Лысков Игорь Витальевич
Статус: Старший модератор
Рейтинг: 47

Перейти к консультации №:
 

Консультация онлайн # 194098
Раздел: • Assembler
Автор вопроса: cupoma58 (Посетитель)
Отправлена: 05.12.2018, 10:59
Поступило ответов: 0

Уважаемые эксперты! Пожалуйста, ответьте на вопрос:

Это простой арифмометр для положительных, целых и дробных чисел (компилятор masm32v11)

Код (Assembler) :: выделить код
;арифметика под coпроцессор
.686
.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 
;-------------------------- 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 
;-------------------------- 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
;-------------------------- 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
;-------------------------- 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       
;----------------------------------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
;-------------------------- 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  
;------------------------------------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
;-------------------------- 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
;-------------------------- 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 
;-------------------------- . (y=120)----------------------------------       
	push    0
	push	[hInst]
    push    0
	push    [ebp+08h]
	push	30	 
	push	30	 
	push	160	 
	push	90	 
	push	STYLBUT
	push	offset butP     
	push	offset clsBut   
	push	0
	call	CreateWindowExA@48
    mov	    hbutP,eax      
;------------------------------------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 
;------------------------------------+(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
;----------------------------------- - (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
;----------------------------------- * (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         
;----------------------------------- : (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           
;------------------------------------=(y=160)-----------------------------------
    push	0
	push	[hInst]
    push    0
	push    [ebp+08h]
	push	30 
	push	30 
	push	160	 
	push	130 
	push	STYLBUT
	push	offset butI     
	push	offset clsBut    
	push	0
	call	CreateWindowExA@48
	mov	    hbutI,eax
;----------------------окно редактирования----------------------------
    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]         
    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  
    je    nabor
    mov   eax,[hbut0]         
    cmp   [ebp+14h],eax           
    je    nabor
    mov   eax,[hbutP]         
    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 16                 ;ёмкость буфера stroka
      push offset stroka         
      push [hedt]             ;куда добавляем        
      call GetWindowTextA@12
      add  eax,offset stroka       
      push 16                                 
      push eax               
      push [EBP+14h]          ;кнопкa
      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,char
      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+ 8h]            ;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 stroka
  push  [hedt]
  call  SetWindowTextA@8                             
  ret
settext  endp
;------------------------- арифметика -----------------------------------------
;операция сложения:
plu  proc                     ;набрали 1-е число и нажали "+"
  pushad                      
  mov  ebx,hbutS              ;запоминаем 
  mov  char,ebx               ;тип операции (аналог->select = "+")                                   
  call slen                   ;длина целой и дробной части 1-го числа
  mov  edx,point              ;дробность
  mov  point1,edx             ;1-го числа
  call asc2float              ;преобразуем 1-ю строку в дв.код
  mov  esi,float
  mov  float1,esi             ;float1=1-й дв.код
  call clproc                 ;очищаем дисплей
  popad
  ret
plu  endp
pluex  proc                   ;набрали 2-е число и нажали "="
  call clproc                 ;очищаем дисплей                      
  call slen                   ;длина целой и дробной части 2-го числа
  call asc2float              ;преобразуем 2-е число в дв.код=>float
  call add_32  
  call float2asc              ;преобразуем итог в строку 
  call settext                ;добавляем итог на дисплей
  ret
pluex  endp
add_32 proc
  finit
  cmp  point1,1               ;1-е число дробное?
  je   a1                     ;да->a1
  fild float1                 ;нет
  jmp  a2            
a1:
  fld  float1
a2:
  cmp  point,1                ;2-е число дробное?
  je   a3                     ;да->a3
  fild float                  ;нет
  jmp  a4
a3:
  fld  float
a4:
  fadd
  fstp res
  ret
add_32 endp
;операция вычитания:
min  proc                 
  pushad                       
  mov  ebx,hbutM              ;запоминаем 
  mov  char,ebx               ;тип операции (аналог->select = "-")  
  call slen                   ;длина целой и дробной части
  mov  edx,point              ;дробность
  mov  point1,edx             ;1-го числа
  call asc2float              ;преобразуем 1-ю строку в дв.код
  mov  esi,float
  mov  float1,esi
  call clproc                 ;очищаем дисплей
  popad
  ret
min  endp
minex  proc
  call clproc                 ;очищаем дисплей                      
  call slen
  call asc2float              ;преобразуем 2-е число в дв.код=>float
  call sub_32  
  call float2asc              ;преобразуем итог в строку 
  call settext                ;добавляем итог на дисплей
  ret
minex  endp
sub_32 proc
  finit
  cmp  point,1                ;2-е число дробное?
  je   s1                     ;да->s1
  fild float                  ;нет
  jmp  s2            
s1:
  fld  float
s2:
  cmp  point1,1               ;1-е число дробное?
  je   s3                     ;да->s3
  fild float1                 ;нет
  jmp  s4
s3:
  fld  float1
s4:
  fsub
  fstp res                     
  ret
sub_32 endp
;операция умножения:
umn  proc
  pushad                       
  mov  ebx,hbutU              ;запоминаем 
  mov  char,ebx               ;тип операции (аналог->select = "*")                                   
  call slen                   ;длина целой и дробной части
  mov  edx,point              ;дробность
  mov  point1,edx             ;1-го числа
  call asc2float              ;преобразуем 1-ю строку в дв.код
  mov  esi,float
  mov  float1,esi             ;float1=1-й дв.код
  call clproc                 ;очищаем дисплей
  popad
  ret
umn  endp
umnex  proc
  call clproc                 ;очищаем дисплей                      
  call slen
  call asc2float              ;преобразуем 2-е число в дв.код
  call mul_32  
  call float2asc              ;преобразуем итог в строку 
  call settext                ;добавляем итог на дисплей
  ret
umnex  endp
mul_32 proc                    
  finit
  cmp  point1,1               ;1-е число дробное?
  je   u1                     ;да->u1
  fild float1                 ;нет
  jmp  u2            
u1:
  fld  float1
u2:
  cmp  point,1                ;2-е число дробное?
  je   u3                     ;да->u3
  fild float                  ;нет
  jmp  u4
u3:
  fld  float
u4:
  fmul
  fstp res                    
  ret
mul_32 endp
;операция деления:
del  proc
  pushad                       
  mov  ebx,hbutD              ;запоминаем 
  mov  char,ebx               ;тип операции (аналог->select = "/")                                   
  call slen                   ;длина целой и дробной части
  mov  edx,point              ;дробность
  mov  point1,edx             ;1-го числа
  call asc2float              ;преобразуем 1-ю строку в дв.код
  mov  esi,float
  mov  float1,esi             ;float1=1-й дв.код
  call clproc                 ;очищаем дисплей
  popad
  ret
del  endp
delex  proc
  call clproc                 ;очищаем дисплей                      
  call slen
  call asc2float
  call div_32  
  call float2asc              ;преобразуем итог в строку 
  call settext                ;добавляем итог на дисплей
  ret
delex  endp
div_32 proc
  finit
  cmp  point,1                ;2-е число дробное?
  je   d1                     ;да->d1
  fild float                  ;нет
  jmp  d2            
d1:
  fld  float
d2:
  cmp  point1,1               ;1-е число дробное?
  je   d3                     ;да->d3
  fild float1                 ;нет
  jmp  d4
d3:
  fld  float1
d4:
  fdiv
  fstp res                     
  ret
div_32 endp
;--------------------- конвертация -----------------------------------------------
;к-во символов целой и дробной части введённого числа:
slen  proc              
  pushad
  xor  eax,eax
  xor  edx,edx
  lea  eax,stroka      ;адрес начала stroka db 16 dup (0)
  mov  point,0         ;инициируем...  (point dd ?)
  mov  cel,0           ;целая часть числа (cel dd ?)
  mov  dro,0           ;дробная часть числа (drob dd ?)
s1:  
  mov  bl,[eax]        ;берём ASCII-символ 
  or   bl,bl           ;есть символ?
  jz   s4              ;нет->s4
  cmp  point,0         ;была точка?
  jne  s3              ;да->s3
  cmp  bl,"."          ;это точка?
  je   s2              ;да->s2
  inc  edx             ;фиксируем символ целой части
  inc  eax             ;смещаемся вправо, к следующему символу
  jmp  s1              ;повторяем
s2:
  mov  cel,edx         ;сохраняем к-во символов целой части stroka
  xor  edx,edx         ;EDX=0
  inc  eax             ;пропускаем точку
  mov  point,1         ;фиксируем её наличие
  jmp  s1
s3:                
  inc  edx             ;фиксируем символ дробной части
  inc  eax             ;смещаемся вправо, к следующему символу
  jmp  s1            
  mov  dro,edx         ;сохраняем к-во символов дробной части stroka
s4:
  popad
  ret    
slen  endp
;преобразуем символы в двоичный код: 
asc2float proc
  pushad
  xor  eax,eax         ;EAX=0
  xor  ebx,ebx         ;EBX=0
  mov  bcel,0          ;инициируем (bcel dd ?)
  mov  ecx,cel         ;счётчик = к-во символов целой части  
  mov  edx,ten         ;EDX=(ten dd 10.0)
  lea  esi,stroka      ;адрес левого ASCII-символа целой части  
cel_cycl:              ;((((0*10)+1)*10+2)*10+3)*10+4 = 1234
  mov  bl,[esi]        ;добавим в EBX ASCII-символ
  or   bl,bl           ;есть символ?
  jz   fin             ;нет->fin
  cmp  bl,"0"          ;это "0"?
  je   d1              ;да->d1 (без целой части)
  and  bl,0Fh          ;убираем 3-ку 
  mul  edx             ;учитываем множитель  
  add  eax,ebx         ;формируем дв.код целой части
  jc   err             ;если переполнение
  inc  esi             ;смещаемся вправо
  loop cel_cycl        ;повторяем
  mov  bcel,eax        ;сохраняем целую часть
  xor  eax,eax         ;EАX=0   
d1:                     
  mov  ecx,dro         ;счётчик=к-во символов дробной части
  mov  edx,aten        ;EDX=(aten dd 1/10)
  xor  ebx,ebx         ;EBX=0
  lea  esi,stroka      ;адрес правого ASCII-символа   
  add  esi,cel         ;дробной 
  add  esi,dro         ;части
dro_cycl:              ;((((4)*0.1+3)*0.1+2)*0.1+1)*0.1+0 = 0.1234
  mov  bl,[esi]        ;добавим в EBX ASCII-символ 
  or   bl,bl           ;есть символ?
  jz   d2              ;нет->d2
  and  bl,0Fh          ;есть->убираем 3-ку 
  mul  edx             ;учитываем множитель  
  add  eax,ebx         ;формируем дв.код дробной части  
  dec  esi             ;смещаемся влево
  loop dro_cycl        ;повторяем
  mul  edx             ;коррекция дробной части  
d2:
  add  eax,bcel        ;ЕАХ=дробная+целая части
  mov  float,eax
  jc   err             ;если переполнение
err:
fin:
  popad
  ret
asc2float endp
;преобразуем двоичный код в символы: 
float2asc  proc        
  pushad
  xor  eax,eax
  xor  esi,esi
  lea  esi,stroka
  lea  eax,res
  mov  edx,5               ;5 цифр в дробной части
  finit
  fld  dword ptr [eax]     ;st = res
  fldz                     ;st=0, st(1)=res
  fcomip st,st(1)	       ;st = res
  jz   zero  	           ;if res = 0 -> zero
  jb   n1                  ;if res < 0 -> n1
  xor  ebx,ebx             ;EBX=0
  dec  ebx                 ;EBX=(-1)
  push ebx                 ;вершина стека -> ESP
  fild dword ptr [esp]     ;st = [esp], st(1) = res
  pop  ebx
  fxch                     ;st<->st(1) --> st = res, st(1) = [esp]
  fmul st,st(1)            ;st = st * st(1) --> res * [esp]
  mov  byte ptr [esi],"-"  ;добавляем в stroka минус
  inc  esi                 ;смещаемся
n1:
  fld1                     ;st=1, st(1)=res
  fcomip st,st(1)          ;st=res
  jz   one                 ;st-st(1) = 0 -> one
  jb   norm                ;st-st(1) < 0 -> norm
  jmp  trans
norm:
  xor  ecx,ecx
  mov  eax,1               ;EAX=1
  push eax
  fld1                     ;st=1, st(1)=res
  fxch                     ;st=res, st(1)=1
rep1:
  fmul dword ptr [esp]     ;st=st*[esp]=st*1
  inc  ecx                 ;счётчик целой части
  fcomi st,st(1)
  jb   n2                   
  jmp  rep1
n2:
  pop  eax                 
trans:
  xchg edx,ecx             ;ECX = число после точки, EDX = до
  add  ecx,edx             ;ECX = число цифр до + после точки
  mov  eax,10              ;EAX=10
  push eax                 ;[esp]->10
  fild dword ptr [esp]     ;st = 10   
  fxch	                   ;st = res, st(1) = 10
rep2:
  fmul st,st(1)            ;st = res * 10
  fld1                     ;st = 1, st(1) = res * 10
  fcmovne st,st(1)         ;копируем, если не равно
  fistp dword ptr [esp]    ;округляем st и выталкиваем в [ESP]
  mov  al,byte ptr [esp]
  fild dword ptr [esp]     ;st = текущее  значение
  fsubp st(1),st
  add  al,30h              ;AL: BCD->ASCII
  mov  byte ptr [esi],al   ;добавляем в stroka
  inc  esi                 ;смещаемся
  dec  edx                 ;EDX-1
  cmp  edx,0               ;закончилась дробная часть?
  jnz  n3                  ;нет -> n3
  mov  byte ptr [esi],"."  ;если EDX = 0 -> добавляем в stroka точку
  inc  esi
n3:
  loop rep2
  pop  eax
  jmp  fin
zero:
  mov  byte ptr [esi],"0"
  jmp  fin
one:
  mov  byte ptr [esi],"1"
  jmp  fin
error:
fin:
  popad
  ret
float2asc  endp    
end  main

Результатом любой арифметической операции является второе введённое число, которое предваряет "0".
Подскажите - что не так? smile

Последнее редактирование 11.12.2018, 13:18 Лысков Игорь Витальевич (Старший модератор)

Состояние: Консультация закрыта

Oтветов пока не поступило.

Мини-форум консультации № 194098

Зенченко Константин Николаевич
Старший модератор

ID: 31795

# 1

= общий = | 10.12.2018, 15:03 | цитировать цитировать  | профиль профиль  |  отправить письмо в личную почту пейджер
cupoma58:

Откуда Вы взяли:

© Цитата: cupoma58
Результатом любой арифметической операции является второе введённое число, которое предваряет "0".


Если в коде имя сonst.inc, первая буква записана кириллицей:


Файл data.inc Вы не выложили, а со старым из вопроса 193474, выдается куча ошибок:
© Цитата: результат компиляции
data.inc(10) : error A2008: syntax error : in structure
data.inc(11) : error A2008: syntax error : in structure
data.inc(33) : error A2044: invalid character in file
data.inc(34) : error A2044: invalid character in file
181210a.asm(13) : error A2006: undefined symbol : wc
181210a.asm(14) : error A2006: undefined symbol : wc
181210a.asm(15) : error A2006: undefined symbol : wc
181210a.asm(16) : error A2006: undefined symbol : wc
181210a.asm(18) : error A2006: undefined symbol : wc
181210a.asm(22) : error A2006: undefined symbol : wc
181210a.asm(26) : error A2006: undefined symbol : wc
181210a.asm(27) : error A2006: undefined symbol : wc
181210a.asm(28) : error A2006: undefined symbol : wc
181210a.asm(29) : error A2006: undefined symbol : wc
181210a.asm(30) : error A2006: undefined symbol : wc
181210a.asm(58) : error A2006: undefined symbol : msg
181210a.asm(62) : error A2006: undefined symbol : msg
181210a.asm(64) : error A2006: undefined symbol : msg
181210a.asm(68) : error A2006: undefined symbol : msg
181210a.asm(247) : error A2006: undefined symbol : butP
181210a.asm(251) : error A2006: undefined symbol : hbutP
181210a.asm(390) : error A2006: undefined symbol : hbutP
181210a.asm(415) : error A2006: undefined symbol : stroka
181210a.asm(418) : error A2006: undefined symbol : stroka
181210a.asm(441) : error A2006: undefined symbol : char
181210a.asm(489) : error A2006: undefined symbol : stroka
181210a.asm(499) : error A2006: undefined symbol : char
181210a.asm(501) : error A2006: undefined symbol : point
181210a.asm(502) : error A2006: undefined symbol : point1
181210a.asm(504) : error A2006: undefined symbol : float
181210a.asm(505) : error A2006: undefined symbol : float1
181210a.asm(521) : error A2006: undefined symbol : point1
181210a.asm(523) : error A2006: undefined symbol : float1
181210a.asm(526) : error A2006: undefined symbol : float1
181210a.asm(528) : error A2006: undefined symbol : point
181210a.asm(530) : error A2006: undefined symbol : float
181210a.asm(533) : error A2006: undefined symbol : float
181210a.asm(543) : error A2006: undefined symbol : char
181210a.asm(545) : error A2006: undefined symbol : point
181210a.asm(546) : error A2006: undefined symbol : point1
181210a.asm(548) : error A2006: undefined symbol : float
181210a.asm(549) : error A2006: undefined symbol : float1
181210a.asm(565) : error A2006: undefined symbol : point
181210a.asm(567) : error A2006: undefined symbol : float
181210a.asm(570) : error A2006: undefined symbol : float
181210a.asm(572) : error A2006: undefined symbol : point1
181210a.asm(574) : error A2006: undefined symbol : float1
181210a.asm(577) : error A2006: undefined symbol : float1
181210a.asm(587) : error A2006: undefined symbol : char
181210a.asm(589) : error A2006: undefined symbol : point
181210a.asm(590) : error A2006: undefined symbol : point1
181210a.asm(592) : error A2006: undefined symbol : float
181210a.asm(593) : error A2006: undefined symbol : float1
181210a.asm(609) : error A2006: undefined symbol : point1
181210a.asm(611) : error A2006: undefined symbol : float1
181210a.asm(614) : error A2006: undefined symbol : float1
181210a.asm(616) : error A2006: undefined symbol : point
181210a.asm(618) : error A2006: undefined symbol : float
181210a.asm(621) : error A2006: undefined symbol : float
181210a.asm(631) : error A2006: undefined symbol : char
181210a.asm(633) : error A2006: undefined symbol : point
181210a.asm(634) : error A2006: undefined symbol : point1
181210a.asm(636) : error A2006: undefined symbol : float
181210a.asm(637) : error A2006: undefined symbol : float1
181210a.asm(653) : error A2006: undefined symbol : point
181210a.asm(655) : error A2006: undefined symbol : float
181210a.asm(658) : error A2006: undefined symbol : float
181210a.asm(660) : error A2006: undefined symbol : point1
181210a.asm(662) : error A2006: undefined symbol : float1
181210a.asm(665) : error A2006: undefined symbol : float1
181210a.asm(677) : error A2006: undefined symbol : stroka
181210a.asm(678) : error A2006: undefined symbol : point
181210a.asm(679) : error A2006: undefined symbol : cel
181210a.asm(680) : error A2006: undefined symbol : dro
181210a.asm(685) : error A2006: undefined symbol : point
181210a.asm(693) : error A2006: undefined symbol : cel
181210a.asm(696) : error A2006: undefined symbol : point
181210a.asm(702) : error A2006: undefined symbol : dro
181210a.asm(712) : error A2006: undefined symbol : bcel
181210a.asm(713) : error A2006: undefined symbol : cel
181210a.asm(715) : error A2006: undefined symbol : stroka
181210a.asm(728) : error A2006: undefined symbol : bcel
181210a.asm(731) : error A2006: undefined symbol : dro
181210a.asm(732) : error A2006: undefined symbol : aten
181210a.asm(734) : error A2006: undefined symbol : stroka
181210a.asm(735) : error A2006: undefined symbol : cel
181210a.asm(736) : error A2006: undefined symbol : dro
181210a.asm(748) : error A2006: undefined symbol : bcel
181210a.asm(749) : error A2006: undefined symbol : float
181210a.asm(761) : error A2006: undefined symbol : stroka

=====
Мне безразлично, что Вы думаете о обо мне, но я рад за Вас - Вы начали думать.
smile

cupoma58
Посетитель

ID: 401688

# 2

= общий = | 11.12.2018, 12:54 | цитировать цитировать  | профиль профиль  |  отправить письмо в личную почту пейджер
Зенченко Константин Николаевич:

data.inc:

;окно:
hInst	   dd 0               ;дескриптор приложения
hWnd	   dd 0               ;дескриптор окна-арифмометра
titleName  db "Aрифмометр_041218",0
className  db "class32",0
clsBut	   db "BUTTON",0
clsEdt     db  "EDIT",0
;явные типы:
butC       db  "C",0
but1       db  "1",0
but2       db  "2",0
but3       db  "3",0
but4       db  "4",0     
but5       db  "5",0
but6       db  "6",0    
but7       db  "7",0
but8       db  "8",0
but9       db  "9",0
but0       db  "0",0      
butS       db  "+",0
butM       db  "-",0
butU       db  "*",0
butD       db  ":",0        
butI       db  "=",0
butP       db  ".",0              
Edt        db  " ",0
stroka     db  16 dup (0)     ;буфер для работы с дисплеем (резервируем и очищаем)
ten        dd  10.0
aten       dd  1/10
;неявные типы:
float      dd  ?
float1     dd  ?                                                                   
res        dq  ?              ;итог арифметической операции 
point      dd  ?              ;шдентификатор "."
point1     dd  ?
point2     dd  ?
cel        dd  ?              ;к-во символов целой части
dro        dd  ?              ;к-во символов дробной части
bcel       dd  ?              ;дв.целая часть
char       dd  ?              ;тип арифметической операции
;---------------------------------------------------------------------------------
hedt       dd  ?
hbutC      dd  ?
hbut1      dd  ?
hbut2      dd  ?
hbut3      dd  ?
hbut4      dd  ?  
hbut5      dd  ?
hbut6      dd  ?
hbut7      dd  ?
hbut8      dd  ?
hbut9      dd  ?
hbut0      dd  ?
hbutS      dd  ?
hbutM      dd  ?
hbutU      dd  ?
hbutD      dd  ?
hbutI      dd  ?
hbutK      dd  ?
hbutP      dd  ?
msg	 MSGSTRUCT <?>
wc	 WNDCLASS  <?>

const.inc:
;библиотеки:
includelib e:\masm32\lib\user32.lib
includelib e:\masm32\lib\kernel32.lib              
;windows.inc:
WM_CLOSE        equ 10h
WM_INITDIALOG   equ 110h    
WM_SETFOCUS		equ 7h
WM_DESTROY		equ 2     ;сообщение приходит при закрытии окна
WM_CREATE		equ 1     ;сообщение приходит при содании окна 
WM_COMMAND		equ 111h  ;сообщение, если что-то происходит с элементами на окне
WM_SETTEXT		equ 0Ch   ;сообщение, позволяющее послать элементу строку
WM_GETTEXT		equ 0Dh   ;сообщение, позволяющее получить строку
;свойства окна:
CS_VREDRAW		equ 1h
CS_HREDRAW		equ 2h
CS_GLOBALCLASS	equ 4000h
WS_TABSTOP		equ 10000h
WS_SYSMENU		equ 80000h
WS_OVERLAPPEDWINDOW equ 0+WS_TABSTOP+WS_SYSMENU
STYLE           equ CS_HREDRAW+CS_VREDRAW+CS_GLOBALCLASS
CS_HREDRAW		equ 2h
BS_DEFPUSHBUTTON equ 1h
WS_VISIBLE		equ 10000000h
WS_CHILD		equ 40000000h
WS_BORDER		equ 800000h
STYLBUT         equ WS_CHILD+BS_DEFPUSHBUTTON+WS_VISIBLE+WS_TABSTOP  ;стиль кнопки
STYLEDT         equ WS_CHILD+WS_VISIBLE+WS_BORDER++WS_TABSTOP  ;стиль дисплея
IDI_APPLICATION	equ 32512  ;идентификатор стандартной иконки
IDC_ARROW		equ 32512  ;идентификатор курсора
SW_SHOWNORMAL	equ 1      ;режим показа окна - нормальный
;типовые прототипы внешних процедур: 
extern	SetFocus@4:NEAR
extern	SendMessageA@16:NEAR
extern	MessageBoxA@16:NEAR
extern	CreateWindowExA@48:NEAR
extern	DefWindowProcA@16:NEAR
extern	DispatchMessageA@4:NEAR
extern	ExitProcess@4:NEAR
extern	GetMessageA@16:NEAR
extern	GetModuleHandleA@4:NEAR
extern	LoadCursorA@8:NEAR
extern	LoadIconA@8:NEAR
extern	PostQuitMessage@4:NEAR
extern	RegisterClassA@4:NEAR
extern	ShowWindow@8:NEAR
extern	TranslateMessage@4:NEAR
extern	UpdateWindow@4:NEAR
extern  SetWindowTextA@8:NEAR
extern  GetWindowTextA@12:NEAR   
;структура сообщений:
MSGSTRUCT STRUC        
MSHWND  	dd ?
MSMESSAGE	dd ?
MSWPARAM	dd ?
MSLPARAM	dd ?
MSTIME	    dd ?
MSPT		dd ?               
MSGSTRUCT ENDS
;структура класса окон:
WNDCLASS STRUC         
CLSSTYLE	dd ?
CLWNDPROC	dd ?
CLSCBCLSEX	dd ?
CLSCBWNDEX	dd ?
CLSHINST	dd ?
CLSHICON	dd ?
CLSHCURSOR	dd ?
CLBKGROUND	dd ?
CLMENNAME	dd ?
CLNAME	    dd ?
WNDCLASS ENDS             

Лысков Игорь Витальевич
Старший модератор

ID: 7438

# 3

= общий = | 11.12.2018, 14:06 | цитировать цитировать  | профиль профиль  |  отправить письмо в личную почту пейджер
cupoma58:

У Вас неправильно работают, наверное, все функции преобразования и вычисления.
1) В буфере лежит числовая строка, начинающаяся с пробела. Это не учитывается.
2) slen возвращает длину целой части (для строки-числа, например, "2") равной 0
3) В asc2float, как минимум, неправильная работа с вещественными числами 10.0 и 0.1
Надо использовать СОПРОЦЕССОР, а не использовать команду MUL
Дальше не вникал... Но, боюсь, еще будет, что исправлять. Начните пока с указанного... smile

=====
"Если вы заметили, что вы на стороне большинства, —
это верный признак того, что пора меняться." Марк Твен

cupoma58
Посетитель

ID: 401688

# 4

= общий = | 25.12.2018, 10:42 | цитировать цитировать  | профиль профиль  |  отправить письмо в личную почту пейджер
Лысков Игорь Витальевич:

Здравствуйте. Когда ошибок очень много - лучше начать заново. Я выбрал другой принцип преобразования
string->float:

                                              
   (((((1*0)+1)*10+2)*10+3)*10+4)*10+5)*10+6=123456:10=12345,6:10=1234,56:10=123,456

Определил длину введённой строки:
  slen  proc 
    pushad 
    xor  eax,eax
    xor  edx,edx
    lea  ebx,stroka           
  cycl:
    mov  dl,[ebx]             <i>;добавляем символ</i>
    or   dl,dl                <i>;есть символ?</i>  
    jz   fin                  <i>;нет->fin</i>
    inc  eax                  <i>;фиксируем символ</i>
    inc  ebx                  <i>;смещаемся</i>
    jmp  cycl                 <i>;повторяем</i>
  fin:
    popad  
  exit:
    ret
  slen  endp

Вернулся к классической FPU-арифметике (например-сложение):
add_32  proc
  finit
  fld  float1
  fld  float
  fadd
  fstp res
  ret
add_32  endp

И преобразовал строку в число, с использованием FPU:
  asc2float proc
    pushad
    lea  esi,stroka
    lea  edi,float
    call slen                       ;получаем длину stroka                
    mov  ecx,eax                ;ЕСХ=>длина stroka
    mov  edx,eax                ;EDX=>длина stroka
    mov  ebx,ten                ;EBX=(ten dd 10)
    xor  eax,eax                 ;EAX=0
    push eax                       ;[ESP]=0
    finit
    fldz                               ;st=0
  cycl:                               ;цикл обработки stroka
    cmp  byte ptr [esi],"0"     ;это 0? 
    jnb  c1                             ;не меньше->с1 
    cmp  byte ptr [esi],dot     ;это точка?
    jnz  err                    
    jmp  cont                        ;да->cont 
  c1:                                   ;(((0*10)+1)*10+2)*10+3=123
    mov  [esp],ebx              ;[ESP]=10
    fimul dword ptr [esp]       ;st=st*10 
    mov  al,byte ptr [esi]
    sub  al,"0"
    mov  [esp],eax              ;[ESP]=EAX
    fiadd dword ptr [esp]       ;st=st*10+EAX... - накапливаем дв.код
  c2:                          
    dec  ecx                    ;уменьшаем счётчик
    inc  esi                    ;смещаемся/пропускаем точку
    cmp  ecx,0                  ;закончились символы?
    jnz  cycl                   ;нет-повторяем
  final:                        ;определяем размер дробной части:                      
    xchg esi,edi                ;EDI<->stroka, ESI<->float
    mov  al,dot                 ;загружаем точку
    mov  ecx,edx                ;ECX=длина stroka
    sub  edi,edx                
    repnz scasb                 ;ищем точку по адресу ES:(E)DI и уменьшаем счётчик, в итоге: 
                                        ;ECX=количество символов после запятой
    cmp  ecx,0                    ;число дробное?
    jz   fin                           ;нет->fin
    mov  dword ptr [esp],ten    ;да...
  drob:                                     ;...обрабатываем дробную часть
    fidiv dword ptr [esp]          ;st=st/10, по ЕСХ
    loop drob
  fin:
    fstp dword ptr [esi]           ;сохраняем float
  err:
    pop  eax                     
    popad
    ret
  asc2float endp 

Кое-что изменилось - теперь в результате всех операций имеем "0". Такое впечатление, что арифметика
не работает и в сравнении (float2asc):
        ...
        lea  eax,res
        fld  dword ptr [eax]   ;st=res
        ...
        fldz                            ;st=0, st(1)=res
        fcomip st,st(1)	          ;st=res
        jz   ze_ro                  ;если res=0
        ...
    zero:
       mov  byte ptr [esi],"0"
       jmp  fin 
        ...

срабатывает последняя команда - "jz".

Лысков Игорь Витальевич
Старший модератор

ID: 7438

# 5

= общий = | 25.12.2018, 15:51 | цитировать цитировать  | профиль профиль  |  отправить письмо в личную почту пейджер
cupoma58:

Хорошо, на досуге гляну. Пока занят

=====
"Если вы заметили, что вы на стороне большинства, —
это верный признак того, что пора меняться." Марк Твен

cupoma58
Посетитель

ID: 401688

# 6

= общий = | 04.01.2019, 10:22 | цитировать цитировать  | профиль профиль  |  отправить письмо в личную почту пейджер
Лысков Игорь Витальевич:

Здравствуйте и с наступившим. Я доделал арифмометр и он заработал, правда - странно. Он не
различает "дробность" введённого числа: число 123.456 он воспринимает как число 123456.
Это последний вариант ASCII To Float:

Код (Assembler) :: выделить код
  asc2float proc
  pushad
  lea  esi,float              ;EDI->первый байт float
  lea  edi,stroka             ;ESI->первый символ stroka 
  call slen                   ;получаем длину строки                
  mov  ecx,len                ;ЕСХ->длина строки (len  dd  ?)
  mov  ebx,ten                   
  xor  eax,eax                ;EAX=0                            
  push eax                    ;[ESP]->0
  finit  
  fldz                        ;st=0
cycl:                         ;цикл обработки строки:
  mov  al,[edi]               ;берём байт
  or   al,al
  jz   err                    ;ничего нет
  cmp  al,"0"                 ;0?
  jae  cycl_int               ;>=
  cmp  al,"."                 ;это точка?
  je   cycl_hlp               ;=
cycl_int:                     ;(((0*10)+1)*10+2)*10+3=123
  mov  [esp],ebx              ;[ESP]<-10
  fimul dword ptr [esp]       ;st=st*10...                    
  and  al,0Fh                 ;ASCII->BCD
  movzx eax,al
  mov  [esp],eax              ;[ESP]<-EAX
  fiadd dword ptr [esp]       ;st=st*10+EAX...<-накапливаем дв.код
cycl_hlp:                          
  dec  ecx                    ;уменьшаем счётчик
  inc  esi                    ;смещаемся/пропускаем точку
  test ecx,ecx                ;закончились символы?
  jnz  cycl                   ;нет-повторяем
drob_len:                     ;определям размер дробной части:
  mov  ecx,len                ;ECX->к-во символов в строке, для цикла
  cld                         ;направление сканирования
  mov  al,"."                 ;загружаем точку    
  repne scasb                 ;ищем точку по адресу ES:(E)DI, в ECX осталось количество символов после точки
  test ecx,ecx                ;число дробное?
  jz   fin                    ;нет->fin
  mov  [esp],ebx              ;[ESP]<-10
get_drob:                     ;обрабатываем дробную часть:
  fidiv dword ptr [esp]       ;st=st/10 
  loop get_drob               ;по ЕСХ
fin:
  fstp dword ptr [esi]        ;сохраняем итог во float
err:
  pop  eax                    
  popad
  ret
  asc2float endp

Подскажите пожалуйста - что не так?
И ещё один момент. Я воспользовался вашим вариантом float2ascii (переделал под win32), со
ссылкой. За это - отдельная благодарность. В этом преобразовании в стек идёт временная ячейка с цифрой, а из стека, для преобразования в ASCII-символ, достаётся регистр ЕАХ. Какая тут связь?

-----
Последнее редактирование 04.01.2019, 12:01 Лысков Игорь Витальевич (Старший модератор)

Лысков Игорь Витальевич
Старший модератор

ID: 7438

# 7

= общий = | 04.01.2019, 13:39 | цитировать цитировать  | профиль профиль  |  отправить письмо в личную почту пейджер

Я бы сделал так:

Код (Assembler) :: выделить код
 asc2float proc 
  pushad 
  lea  edi,float              ;EDI->первый байт float 
  lea  esi,stroka             ;ESI->первый символ stroka  
  finit  
  fldz                        ;st=0 
  mov  ecx,-1            ; признак отсутствия дробной части
cycl:                         ;цикл обработки строки: 
  lodsb	                      ;берём байт 
  or   al,al 
  jz   fin                    ;ничего нет, на выход
  cmp  al,"."                 ;это точка? 
  jne  cycl_digit

  test ecx,ecx
  jge  fin                  ;конроль повторной точки
  xor  ecx,ecx           ;счетчик цифр дробной части
  jmp  cycl

cycl_digit:
  cmp  al,'0'
  jb   fin
  cmp  al,'9'
  ja   fin

  fmul ten                    ;st=st*10...                     
  and  eax,0Fh                ;ASCII->BCD 
  mov  [esp],eax              ;[ESP]<-EAX 
  fiadd dword ptr [esp]       ;st=st*10+EAX...<-накапливаем дв.код 
  test ecx,ecx
  jl   cycl                    ;только целая часть
  inc  ecx                   ;считаем цифры дробной части
  jmp  cycl

fin:
  test  ecx,ecx
  jle save_float           ;есть ли цифры дробной части
  fdiv  ten
  dec	ecx
  jmp	fin

save_float:
  fstp dword ptr [edi]        ;сохраняем итог во float 
  popad 
  ret 
  asc2float endp

При условии, что
Код (Assembler) :: выделить код
ten dd 10.0

Кстати, почему при вводе числа нет проверки на недопустимые символы:
вводятся как буквы, так и несколько точек.
Кстати, как насчет отрицательных чисел? На будущее? smile

В данной подпрограмме добавил проверку на повтор точки и цифры

Что касается этого:
© Цитата:
В этом преобразовании в стек идёт временная ячейка с цифрой, а из стека, для преобразования в ASCII-символ, достаётся регистр ЕАХ
Так это обычное преобразование числа в строку символов. Причем в обратном порядке, в стек заносится, начиная с младшего разряда, а выводить надо, начиная со старшего. Поэтому и используется стек. Извлекается в EAX, чтобы сделать символ и записать на свое место.

=====
"Если вы заметили, что вы на стороне большинства, —
это верный признак того, что пора меняться." Марк Твен

cupoma58
Посетитель

ID: 401688

# 8

= общий = | 09.01.2019, 10:40 | цитировать цитировать  | профиль профиль  |  отправить письмо в личную почту пейджер
Лысков Игорь Витальевич:

Благодарю за подсказку, буду пробовать. Что касается проверок - Вы слишком строги к пенсионеру. Хотя...
smile

cupoma58
Посетитель

ID: 401688

# 9

= общий = | 18.01.2019, 10:21 | цитировать цитировать  | профиль профиль  |  отправить письмо в личную почту пейджер
Лысков Игорь Витальевич:

Здравствуйте. Я изменил один из вариантов и арифмометр заработал, но...возникли проблемы с
точностью результата:

  7 : 2 = 3.5 * 2 = 6.5999      30.5 * 2 = 60     35.5 * 2 = 71
  9 : 2 = 4.5 * 2 = 8.8000      50.5 * 2 = 100    55.5 * 2 = 111   
 11 : 2 = 5.5 * 2 = 11          и т.д.
 13 : 2 = 6.5 * 2 = 13.1999
 15 : 2 = 7.5 * 2 = 15.3999

Погрешность появляется вместе с дробной частью. Я подумал, что это связано с округлением и
попробовал изменить настройку слова управления сопроцессора - ничего не изменилось.
И на числа меньше единицы арифмометр реагирует как на ноль. smile
Подскажите - в чём дело?

Лысков Игорь Витальевич
Старший модератор

ID: 7438

# 10

= общий = | 18.01.2019, 11:30 | цитировать цитировать  | профиль профиль  |  отправить письмо в личную почту пейджер
cupoma58:

Выложите весь код. Посмотрим.

=====
"Если вы заметили, что вы на стороне большинства, —
это верный признак того, что пора меняться." Марк Твен

cupoma58
Посетитель

ID: 401688

# 11

= общий = | 22.01.2019, 09:53 | цитировать цитировать  | профиль профиль  |  отправить письмо в личную почту пейджер
Лысков Игорь Витальевич:

Здравствуйте. Компактнее не получилось:
drobi_3.asm

;арифметика под coпроцессор
.686
.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 
;-------------------------- 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 
;-------------------------- 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
;-------------------------- 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
;-------------------------- 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       
;----------------------------------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
;-------------------------- 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  
;------------------------------------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
;-------------------------- 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
;-------------------------- 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 
;-------------------------- . (y=120)----------------------------------       
	push    0
	push	[hInst]
    push    0
	push    [ebp+08h]
	push	30	 
	push	30	 
	push	160	 
	push	90	 
	push	STYLBUT
	push	offset butP     
	push	offset clsBut   
	push	0
	call	CreateWindowExA@48
    mov	    hbutP,eax      
;------------------------------------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 
;------------------------------------+(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
;----------------------------------- - (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
;----------------------------------- * (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         
;----------------------------------- : (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           
;------------------------------------=(y=160)-----------------------------------
    push	0
	push	[hInst]
    push    0
	push    [ebp+08h]
	push	30 
	push	30 
	push	160	 
	push	130 
	push	STYLBUT
	push	offset butI     
	push	offset clsBut    
	push	0
	call	CreateWindowExA@48
	mov	    hbutI,eax
;----------------------окно редактирования----------------------------
    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]         
    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  
    je    nabor
    mov   eax,[hbut0]         
    cmp   [ebp+14h],eax           
    je    nabor
    mov   eax,[hbutP]         
    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 16                 ;ёмкость буфера stroka
      push offset stroka         
      push [hedt]             ;куда добавляем        
      call GetWindowTextA@12
      add  eax,offset stroka       
      push 16                                 
      push eax               
      push [EBP+14h]          ;кнопкa
      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,char
      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+ 8h]            ;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 stroka
  push  [hedt]
  call  SetWindowTextA@8                             
  ret
settext  endp
;------------------------- арифметика -----------------------------------------
plu  proc                     ;набрали 1-е число и...
  push eax
  push ebx                      
  mov  eax,hbutS              ;запоминаем 
  mov  char,eax               ;тип операции (аналог->select = "+")                                   
  call asc2float              ;преобразуем 1-ю строку/число в дв.код
  mov  ebx,float
  mov  float1,ebx             ;float1=1-е число в дв. виде
  pop  ebx
  pop  eax
  call clproc                 ;...нажали "+"
  ret
plu  endp
pluex  proc                   ;набрали 2-е число и...
  call clproc                 ;...нажали "="                      
  call asc2float              ;преобразуем 2-е число в дв.код=>float
  call add_32  
  call float2asc              ;преобразуем итог в строку 
  call settext                ;добавляем итог на дисплей
  ret
pluex  endp
add_32 proc
  finit
  fld  float
  fld  float1
  fadd 
  fstp res
  ret
add_32 endp
min  proc                 
  push eax
  push ebx                       
  mov  eax,hbutM               
  mov  char,eax                  
  call asc2float               
  mov  ebx,float
  mov  float1,ebx
  pop  ebx
  pop  eax
  call clproc                  
  ret
min  endp
minex  proc
  call clproc                                       
  call asc2float               
  call sub_32  
  call float2asc               
  call settext                 
  ret
minex  endp
sub_32 proc
  finit
  fld  float1
  fld  float
  fsub
  fstp res                     
  ret
sub_32 endp
umn  proc
  push eax
  push ebx                      
  mov  eax,hbutU               
  mov  char,eax                                                   
  call asc2float
  mov  ebx,float
  mov  float1,ebx              
  pop  ebx
  pop  eax
  call clproc                 
  ret
umn  endp
umnex  proc
  call clproc                                       
  call asc2float               
  call mul_32  
  call float2asc               
  call settext                 
  ret
umnex  endp
mul_32 proc                    
  finit
  fld  float1
  fld  float
  fmul
  fstp res                    
  ret
mul_32 endp
del  proc
  push eax
  push ebx                       
  mov  eax,hbutD               
  mov  char,eax                                                   
  call asc2float               
  mov  ebx,float
  mov  float1,ebx              
  pop  ebx
  pop  eax
  call clproc                  
  ret
del  endp
delex  proc
  call clproc                                       
  call asc2float
  call div_32  
  call float2asc               
  call settext                 
  ret
delex  endp
div_32 proc
  finit
  fld  float1
  fld  float
  fdiv
  fstp res                     
  ret
div_32 endp
;--------------------- конвертация -----------------------------------------------                 
asc2float proc          ;символы "0-9" и "."
  pushad
  mov  dot,0            ;инициируем dot
  lea  esi,stroka
  lea  edi,float
  finit                 ;cwr = 111111 1100 111111b <- расш.точн., к ближ.числу
  cld  
  fldz                  ;st=0=>float
cycl:
  xor  eax,eax
  lodsb                 ;копируем байт/символ из DS:ESI в AL
  cmp  al,0             ;если нет символа
  je   fin              ;на выход
  cmp  dot,0            ;была точка?
  jg   drob             ;да (dot > 0)
  cmp  al,"."           ;это точка?
  je   c_dot            ;да
  and  al,0Fh           ;преобразуем символ
  movzx eax,al          ;расширяем его
  mov  [edi],eax        ;и сохраняем 
c_int:                  ;работаем с целой частью числа
  fimul ten             ;st=0*10...
  fiadd dword ptr [edi] ;st=st*10+float, накапливаем дв.код целой части 
  jmp  cycl             ;повторяем с целой частью
c_dot:                  ;встретили точку
  mov  dot,1h           ;фиксируем наличие точки и преобразуем множитель
  fld1                  ;st=1                st(1)=float<-в начале=0
  fidiv ten             ;st=1:10=0.1         st(1)=float
  fstp aten             ;st=float            aten=0.1                    
  jmp  cycl             ;к след.символу 
drob:                   ;например [.123 equ 0.123]
  fld  aten             ;st=0.1              st(1)<-в начале float=0
  fimul dword ptr [edi] ;st=0.1*1            st(1)=float
  faddp st(1),st        ;st=0.1*1+0...накапливаем дв.код дробной части        
  fld   aten            ;st=0.1              st(1)=float
  fidiv ten             ;st=0.1/10           st(1)=float
  fstp  aten            ;st=float            aten=0.01...
  jmp  cycl             ;повторяем с дробной частью               
fin:
  fstp dword ptr [edi]  ;сохраняем двоичный код во float
  popad
  ret
asc2float endp
;вещественное в ASCII-символы: процедура рабочая
float2asc proc
  pushad
  lea  edi,stroka
  finit                 ;cwr = 111111 1100 111111b <- расш.точн., к ближ.числу
  fld  res              ;st=res (в примере res=73.25)
  ftst                  ;st=0.0? 
  fstsw ax              ;копируем слово состояния, для основного процессора
  sahf                  ;запись АН в EFLAGS,копирует биты: С3->ZF, С2->PF, а С0->СF
  jnz  m1               ;если  res не 0 -> m1  
  mov  ax,"0"           ;добавляем на дисплей 0 -> результат арифметической операции = 0
  stosw                 ;перенос содержимого AL(AX,EAX)в адрес памяти ES:(E)DI
  jmp  m6               ;и - выходим
m1:
  jnc  m2               ;если число "+", нет переноса
  mov  al,"-"           ;если есть перенос - число "-"
  stosb
  fchs                  ;изменяем знак числа
;                       st       st(1)     st(2)     st(3)   ...
m2:                     ;73,25 - условное число, для наглядности
  fld1                  ;1       73,25                
  fld  st(1)            ;73,25     1       73,25      
  fprem                 ; 0,25     1       73,25      
  fsub st(2),st         ; 0,25     1       73         
  fxch st(2)            ;73        1        0,25      
  xor  ecx,ecx          ;ECX=0, готовим счётчик
m3:
  fidiv ten             ; 7.3      1        0.25      
  fxch st(1)            ; 1        7.3      0.25      
  fld  st(1)            ; 7.3      1        7.3       0.25
  fprem                 ; 0.3      1        7.3       0.25
  fsub st(2),st         ; 0.3      1        7         0.25
  fimul ten             ; 3        1        7         0.25
  fistp dig             ; 1        7        0.25      
  inc  ecx              ;уменьшаем счётчик
  push dig              ;сохраняем цифру для преобразования (m4)
  fxch st(1)            ; 7        1        0.25      
  ftst                  ;st=0.0?
  fstsw ax
  sahf 
  jnz  m3               ;если цифра не 0 - повторяем
m4:
  pop  eax              ;выталкиваем/копируем цифру в ЕАХ->AL
  add  al,30h           ;и преобразуем в символ
  stosb                 ;добавляем в stroka
  loop m4               ; 0        1        0.25      
;дробная часть:  если есть
  fstp st               ; 1        0.25            
  fxch st(1)            ; 0.25     1
  ftst
  fstsw ax
  sahf
  jz   m6               ;если дробная часть = 0
  mov  al,"."           ;добавляем точку в stroka
  stosb
  mov  ecx,fore         ;заряжаем счётчик - 4 знакa после "."
m5:
  fimul ten             ; 2.5       1
  fxch st(1)            ; 1         2.5
  fld  st(1)            ; 2.5       1       2.5
  fprem                 ; 0.5       1       2.5
  fsub st(2),st         ; 0.5       1       2
  fxch st(2)            ; 2         1       0.5
  fistp dig             ; 1         0.5
  mov  eax,dig          ;EAX = dig
  add  al,30h           ;преобразуем цифру 
  stosb                 ;и добавляем в stroka
  fxch st(1)            ; 0.5       1
  ftst                  ;если остаток не 0
  fstsw ax
  sahf                  ;повторяем по счётчику
  loopnz m5             ; 0         1 
m6:
  fstp st               ; 1
  fstp st               ; ... почистились
  mov  byte ptr [edi],0 ;закрываем stroka
fin:
  popad
  ret
float2asc endp 
end  main

data.inc
;окно:
hInst	   dd 0               ;дескриптор приложения
hWnd	   dd 0               ;дескриптор окна-арифмометра
titleName  db "Aрифмометр_160119",0
className  db "class32",0
clsBut	   db "BUTTON",0
clsEdt     db  "EDIT",0
;явные типы:
butC       db  "C",0
but1       db  "1",0
but2       db  "2",0
but3       db  "3",0
but4       db  "4",0     
but5       db  "5",0
but6       db  "6",0    
but7       db  "7",0
but8       db  "8",0
but9       db  "9",0
but0       db  "0",0      
butS       db  "+",0
butM       db  "-",0
butU       db  "*",0
butD       db  ":",0        
butI       db  "=",0
butP       db  ".",0              
Edt        db  " ",0
stroka     dd  16 dup (0)     ;буфер для работы с дисплеем (резервируем и очищаем)
ten        dd  10
fore       dd  4
;неявные типы:
dot        db  ?
aten       dd  ?
float      dd  ?
float1     dd  ?                                                                    
char       dd  ?              ;тип арифметической операции
res        dq  ?
dig        dd  ?  
;---------------------------------------------------------------------------------
hedt       dd  ?
hbutC      dd  ?
hbut1      dd  ?
hbut2      dd  ?
hbut3      dd  ?
hbut4      dd  ?  
hbut5      dd  ?
hbut6      dd  ?
hbut7      dd  ?
hbut8      dd  ?
hbut9      dd  ?
hbut0      dd  ?
hbutS      dd  ?
hbutM      dd  ?
hbutU      dd  ?
hbutD      dd  ?
hbutI      dd  ?              ; "="
hbutP      dd  ?              ; "."
msg	 MSGSTRUCT <?>
wc	 WNDCLASS  <?>               

const.inc
;библиотеки:
includelib c:\masm32\lib\user32.lib
includelib c:\masm32\lib\kernel32.lib              
;windows.inc:
WM_CLOSE        equ 10h
WM_INITDIALOG   equ 110h    
WM_SETFOCUS		equ 7h
WM_DESTROY		equ 2     ;сообщение приходит при закрытии окна
WM_CREATE		equ 1     ;сообщение приходит при содании окна 
WM_COMMAND		equ 111h  ;сообщение, если что-то происходит с элементами на окне
WM_SETTEXT		equ 0Ch   ;сообщение, позволяющее послать элементу строку
WM_GETTEXT		equ 0Dh   ;сообщение, позволяющее получить строку
;свойства окна:
CS_VREDRAW		equ 1h
CS_HREDRAW		equ 2h
CS_GLOBALCLASS	equ 4000h
WS_TABSTOP		equ 10000h
WS_SYSMENU		equ 80000h
WS_OVERLAPPEDWINDOW equ 0+WS_TABSTOP+WS_SYSMENU
STYLE           equ CS_HREDRAW+CS_VREDRAW+CS_GLOBALCLASS
CS_HREDRAW		equ 2h
BS_DEFPUSHBUTTON equ 1h
WS_VISIBLE		equ 10000000h
WS_CHILD		equ 40000000h
WS_BORDER		equ 800000h
STYLBUT         equ WS_CHILD+BS_DEFPUSHBUTTON+WS_VISIBLE+WS_TABSTOP  ;стиль кнопки
STYLEDT         equ WS_CHILD+WS_VISIBLE+WS_BORDER++WS_TABSTOP  ;стиль дисплея
IDI_APPLICATION	equ 32512  ;идентификатор стандартной иконки
IDC_ARROW		equ 32512  ;идентификатор курсора
SW_SHOWNORMAL	equ 1      ;режим показа окна - нормальный
;типовые прототипы внешних процедур: 
extern	SetFocus@4:NEAR
extern	SendMessageA@16:NEAR
extern	MessageBoxA@16:NEAR
extern	CreateWindowExA@48:NEAR
extern	DefWindowProcA@16:NEAR
extern	DispatchMessageA@4:NEAR
extern	ExitProcess@4:NEAR
extern	GetMessageA@16:NEAR
extern	GetModuleHandleA@4:NEAR
extern	LoadCursorA@8:NEAR
extern	LoadIconA@8:NEAR
extern	PostQuitMessage@4:NEAR
extern	RegisterClassA@4:NEAR
extern	ShowWindow@8:NEAR
extern	TranslateMessage@4:NEAR
extern	UpdateWindow@4:NEAR
extern  SetWindowTextA@8:NEAR
extern  GetWindowTextA@12:NEAR   
;структура сообщений:
MSGSTRUCT STRUC        
MSHWND  	dd ?
MSMESSAGE	dd ?
MSWPARAM	dd ?
MSLPARAM	dd ?
MSTIME	    dd ?
MSPT		dd ?               
MSGSTRUCT ENDS
;структура класса окон:
WNDCLASS STRUC         
CLSSTYLE	dd ?
CLWNDPROC	dd ?
CLSCBCLSEX	dd ?
CLSCBWNDEX	dd ?
CLSHINST	dd ?
CLSHICON	dd ?
CLSHCURSOR	dd ?
CLBKGROUND	dd ?
CLMENNAME	dd ?
CLNAME	    dd ?
WNDCLASS ENDS             


smile

 

Возможность оставлять сообщения в мини-форумах консультаций доступна только после входа в систему.
Воспользуйтесь кнопкой входа вверху страницы, если Вы зарегистрированы или пройдите простую процедуру регистрации на Портале.

Яндекс Rambler's Top100

главная страница | поддержка | задать вопрос

Время генерирования страницы: 0.22839 сек.

© 2001-2019, Портал RFPRO.RU, Россия
Калашников О.А.  |  Гладенюк А.Г.
Версия системы: 7.77 от 31.05.2019
Версия JS: 1.34 | Версия CSS: 3.35