2. Разработка программы
В данном разделе представлен текст программы для подсчёта функции, заданной индивидуальным заданием в соответствии с алгоритмом из предыдущего раздела. Текст программы из файла "in out loga(x).asm" представлен на рисунке 3.
;*************************************************************************** ;Волков ;Арифметический сопроцессор; ;Шестнадцатеричная; ; Плавающая точка (нормальная форма); ; ; ;*************************************************************************** .686 .model flat,stdcall option casemap:none WinMain proto :DWORD,:DWORD,:DWORD,:DWORD include masm32includewindows.inc include masm32includeuser32.inc include masm32includekernel32.inc includelib masm32libuser32.lib includelib masm32libkernel32.lib include masm32includemasm32.inc includelib masm32libmasm32.lib .data ClassName db "SimpleWinClass",0 AppName db "5adb",0 MenuName db "FirstMenu",0 ButtonClassName db "button",0 ButtonText db "Calculate logA(X)",0 StaticClassName db "static",0 StaticText db "Enter number X", 0 StaticText1 db "Enter number A", 0 EditClassName db "edit",0 TestString db "Wow! Im in an edit box now",0 hwndStatic1 dd 0 hwndStatic2 dd 0 dexpx dd 0 dexpmx dd 0 zero dq 0.0 integer dd 0.0 fractional dd 0.0 fractional_buffer dd 0.0 hex dd 16.0 counter dd 1 divider dd 1 hexInt dd 16 buffer_out db 512 dup(0) .data? hInstance HINSTANCE ? CommandLine LPSTR ? hwndButton HWND ? hwndEdit HWND ? hwndEdit1 HWND ? buffer db 512 dup(?) angle dq ? angle1 dq ? angle_read dq ? angle_buffer dd ? |
|
.const ButtonID equ 1 EditID equ 2 StaticID equ 3 IDM_HELLO equ 1 IDM_CLEAR equ 2 IDM_GETTEXT equ 3 IDM_EXIT equ 4 const_log dq 1.0 .code start: invoke GetModuleHandle, NULL mov hInstance,eax invoke GetCommandLine mov CommandLine,eax invoke WinMain, hInstance,NULL,CommandLine, SW_SHOWDEFAULT invoke ExitProcess,eax WinMain proc hInst:HINSTANCE,hPrevInst:HINSTANCE,CmdLine:LPSTR,CmdShow:DWORD LOCAL wc:WNDCLASSEX LOCAL msg:MSG LOCAL hwnd:HWND mov wc.cbSize,SIZEOF WNDCLASSEX mov wc.style, CS_HREDRAW or CS_VREDRAW mov wc.lpfnWndProc, OFFSET WndProc mov wc.cbClsExtra,NULL mov wc.cbWndExtra,NULL push hInst pop wc.hInstance mov wc.hbrBackground,COLOR_BTNFACE+1 mov wc.lpszMenuName,OFFSET MenuName mov wc.lpszClassName,OFFSET ClassName invoke LoadIcon,NULL,IDI_APPLICATION mov wc.hIcon,eax mov wc.hIconSm,eax invoke LoadCursor,NULL,IDC_ARROW mov wc.hCursor,eax invoke RegisterClassEx, addr wc INVOKE CreateWindowEx,WS_EX_CLIENTEDGE,ADDR ClassName,ADDR AppName, WS_OVERLAPPEDWINDOW,CW_USEDEFAULT, CW_USEDEFAULT,300,200,NULL,NULL, hInst,NULL mov hwnd,eax INVOKE ShowWindow, hwnd,SW_SHOWNORMAL INVOKE UpdateWindow, hwnd .WHILE TRUE INVOKE GetMessage, ADDR msg,NULL,0,0 .BREAK .IF (!eax) INVOKE TranslateMessage, ADDR msg INVOKE DispatchMessage, ADDR msg .ENDW mov eax,msg.wParam ret WinMain endp WndProc proc hWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM .IF uMsg==WM_DESTROY invoke PostQuitMessage,NULL .ELSEIF uMsg==WM_CREATE ; static1 |
|
invoke CreateWindowEx,WS_EX_CLIENTEDGE, ADDR StaticClassName, ADDR StaticText, WS_CHILD or WS_VISIBLE or WS_BORDER or ES_LEFT or ES_AUTOHSCROLL, 50,15,200,25,hWnd,StaticID,hInstance,NULL mov hwndStatic1,eax ; edit1 invoke CreateWindowEx,WS_EX_CLIENTEDGE, ADDR EditClassName,NULL, WS_CHILD or WS_VISIBLE or WS_BORDER or ES_LEFT or ES_AUTOHSCROLL, 50,35,200,25,hWnd,EditID,hInstance,NULL mov hwndEdit,eax invoke SetFocus, hwndEdit ; static2 invoke CreateWindowEx,WS_EX_CLIENTEDGE, ADDR StaticClassName, ADDR StaticText1, WS_CHILD or WS_VISIBLE or WS_BORDER or ES_LEFT or ES_AUTOHSCROLL, 50,70,200,25,hWnd,StaticID,hInstance,NULL mov hwndStatic1,eax ; edit2 invoke CreateWindowEx,WS_EX_CLIENTEDGE, ADDR EditClassName,NULL, WS_CHILD or WS_VISIBLE or WS_BORDER or ES_LEFT or ES_AUTOHSCROLL, 50,90,200,25,hWnd,EditID,hInstance,NULL mov hwndEdit1,eax ; button invoke CreateWindowEx,NULL, ADDR ButtonClassName,ADDR ButtonText, WS_CHILD or WS_VISIBLE or BS_DEFPUSHBUTTON, 75,125,140,25,hWnd,ButtonID,hInstance,NULL mov hwndButton,eax .ELSEIF uMsg==WM_COMMAND mov eax,wParam .IF lParam==0 .IF ax==IDM_HELLO invoke SetWindowText,hwndEdit,ADDR TestString invoke SendMessage,hwndEdit,WM_KEYDOWN,VK_END,NULL .ELSEIF ax==IDM_CLEAR invoke SetWindowText,hwndEdit,NULL .ELSEIF ax==IDM_GETTEXT ; get number from edit invoke GetWindowText,hwndEdit,ADDR buffer,512 ;invoke StrToFloat, ADDR buffer, ADDR angle ; преобразуем из ASCII в число с плавающей точкой двойной точности в angle lea esi, buffer call readdec fld angle_read fstp qword ptr[angle] mov ecx, 20 lea esi, buffer buffer_cliner1: mov byte ptr[esi],0 inc esi loop buffer_cliner1 |
|
invoke GetWindowText,hwndEdit1,ADDR buffer,512 ;invoke StrToFloat, ADDR buffer, ADDR angle1 ; преобразуем из ASCII в число с плавающей точкой двойной точности в angle lea esi, buffer call readdec fld angle_read fstp qword ptr[angle1] finit ; инициализация сопроцессора fld const_log fld angle FYL2X fld const_log fld angle1 FYL2X FDIVP st(1), st(0) fstp qword ptr[angle] mov ecx, 20 lea esi, buffer buffer_cliner2: mov byte ptr[esi],0 inc esi loop buffer_cliner2 invoke FloatToStr, angle, ADDR buffer call DecToHex invoke MessageBox,NULL,ADDR buffer_out ,ADDR AppName,MB_OK .ELSE invoke DestroyWindow,hWnd .ENDIF .ELSE .IF ax==ButtonID shr eax,16 .IF ax==BN_CLICKED invoke SendMessage,hWnd,WM_COMMAND,IDM_GETTEXT,0 .ENDIF .ENDIF .ENDIF .ELSE invoke DefWindowProc,hWnd,uMsg,wParam,lParam ret .ENDIF xor eax,eax ret WndProc endp readdec proc ;процедура преобразования символьной строки по адресу ESI в число в сопроцессоре fld zero fstp dword ptr[integer] fld zero fstp dword ptr[fractional] fld zero fstp dword ptr[fractional_buffer] mov counter, 1 |
|
xor eax, eax xor edx, edx xor ecx, ecx mov ebx,16 int_part_read: mov cl,byte ptr[esi] cmp cl, , jne int_part_read_jump1 mov byte ptr[esi],. int_part_read_jump1: cmp cl ,. ; jnz int_part_read_jump2 inc esi mov integer,eax ; saved integer part of number jmp fractional_part_read int_part_read_jump2: .IF (cl>29h && cl<40h); sub cl,30h ; .ELSEIF (cl>40h && cl<47h); sub cl,37h ; .ELSEIF (cl>60h && cl<67h); sub cl,57h ; .ENDIF mul bl add ax,cx inc esi jmp int_part_read fractional_part_read: xor eax, eax mov al,byte ptr[esi] .IF( al == 0h) ; string termintor jmp unknow .ELSEIF (al>29h && al<40h); sub al,30h ; .ELSEIF (al>40h && al<47h); sub al,37h ; .ELSEIF (al>60h && al<67h); sub al,57h .ENDIF mov ecx, counter mov fractional_buffer, eax fild fractional_buffer modulo_division: fdiv hex loop modulo_division fadd fractional fstp fractional inc counter inc esi jmp fractional_part_read |
|
unknow: fild integer fadd fractional fstp angle_read ret readdec endp DecToHex proc ;процедура преобразования символьной строки по адресу ESI в символьню строку по адресу EDI mov counter, 0 lea esi, buffer xor eax,eax;обнуление eax mov ebx,10 ; основание системы счисления mov cl, byte ptr [esi] ; проверка ввода "-" cmp cl,- ; jne DecToHex_m2 jmp exit DecToHex_m2: mov cl, byte ptr [esi] cmp cl,2Eh ; 2E - it is the point je DecToHex_m1 sub cl, 30h ;перевод из ASCII mul ebx add eax,ecx inc esi;переход к следующему байту массива jmp DecToHex_m2 DecToHex_m1: inc esi xor ecx,ecx DecToHex_m3: mov ebx, eax and ebx, 0000000fh add bl, 30h .if(bl > 39h) add bl, 7 .endif push ebx inc ecx shr eax, 4 cmp eax, 0 jne DecToHex_m3 lea edi, buffer_out DecToHex_m4: pop ebx mov byte ptr [edi], bl inc edi loop DecToHex_m4 mov byte ptr[edi], 2Eh ; ставим разделитель inc edi ; ************ с целой частью закончили xor eax,eax;обнуление eax mov ebx,10 ; основание системы счисления |
|
DecToHex_m5: mov cl, byte ptr [esi] cmp cl, 0 ; 0 - it is end of number je DecToHex_m6 sub cl, 30h ;перевод из ASCII mul ebx add eax,ecx inc esi;переход к следующему байту массива jmp DecToHex_m5 DecToHex_m6: cmp eax,0 jnz DecToHex_m7 mov byte ptr[edi], 30h ; ставим ноль и уходим jmp DecToHex_End DecToHex_m7: .if(eax >= 0 && eax < 10) mov divider, 10 .elseif(eax >= 10 && eax < 100) mov divider, 100 .elseif(eax >= 100 && eax < 1000) mov divider, 1000 .elseif(eax >= 1000 && eax < 10000) mov divider, 10000 .elseif(eax >= 10000 && eax < 100000) mov divider, 100000 .elseif(eax >= 100000 && eax < 1000000) mov divider, 1000000 .elseif(eax >= 1000000 && eax < 10000000) mov divider, 10000000 .elseif(eax >= 10000000 && eax < 100000000) mov divider, 100000000 .elseif(eax >= 100000000 && eax < 1000000000) mov divider, 1000000000 .endif mul hexInt div divider add al, 30h .if(al > 39h) add al, 7 .endif mov byte ptr[edi], al inc edi cmp edx,0 jz DecToHex_End mov eax,edx inc counter cmp counter, 2 ja DecToHex_End jmp DecToHex_m7 DecToHex_End: exit: ret DecToHex endp end start |
Рисунок 3 - Текст программы "in out loga(x).asm"
- Диалоговые окна Извлечение данных из диалогового окна
- Диалоговые окна
- Разработка диалогового окна
- Диалоговое окно
- 4.2.3. Разработка диалогового окна
- Диалоговые окна
- Диалоговые окна
- Объект UserForm (диалоговое окно), коллекция UserForms (диалоговые окна)
- Диалоговые окна Извлечение данных из диалогового окна
- 5.1. Разработка нестандартных диалоговых окон