График функции по Assembler’у

Министерство Образования РФ

Южно-Уральский Государственный Университет

Приборостроительный факультет

Кафедра Автоматики и Управления

















Курсовая работа по Assembler’у.









Выполнил: Копылов Е.Е.

Группа: ПС-116

Проверила: Вставская Е.В.







Челябинск 2008 год


Задание.



Нарисовать график X=3sint+sin5t; Y=2cos3t+sint


Описание решения задачи.



Подключается файл win.inc, к котором хранятся некоторые константы, используемые в программе. В сегменте данных объявляются переменные: декриптор окна консоли, дескриптор совместимого окна консоли, дескриптор приложения, название окна консоли, дескриптор контекста окна, ширина, высота, x, y, t, cons, deg_rad=180, offsetX, offsetY (смещения начала отсчета графика относительно осей Оx и Oy),scaleX, scaleY (масштаб по X и Y).

В сегменте кода вызывается функция GetModuleHandle, при помощи которой получаем дескриптор приложения, после чего помещаем его в eax. Далее заполняем структуру окна стиль. Подключаем процедуру обработки сообщений. Загружаем иконку и курсор с помощью вызова функций LoadIcon и LoadCursor. Задаем цвет фона окна с помощью функции CreateSolidBrush. Регестрируем класс окна с помощью функции RegisterClass. Далее создаем окно зарегестрированного класса с помощью функции CreateWindowEx. Сравниваем eax с нулем. Если он равен 0, то переходим на метку END_LOOP. Помещаем дескриптор окна в регистр eax. Отображаем созданное окно с помощью функции ShowWindow и перерисовываем видимую часть окна при помощи UpdateWindow. Далее следует цикл обработки сообщений, после которого вызывается функция ExitProcess.

После главной функции следует процедура окна. Полученное сообщение сравнивается с сообщениями WM_DESTROY, WM_CREATE, WM_SIZE, WM_PAINT. В случае соответствия следует переход на соответствующую метку.

WMSIZE: Дескриптор совместимого окна консоли сравнивается с 0 и если не равен, то переходим на метку WMCREATE. В противном случае удаляем контекст окна. 

WMCREATE: Передаем дескриптор окна и помещаем его в eax. Создаем совместимый контекст окна с помощью функции CreateCompatibleDC и помещаем дескриптор совместимого контекста в регистр eax. Получаем размер окна при его изменении с помощью функции GetWindowRect. Находим высоту и ширину данного размера окна. Создаем карту бит для данного контекста окна с помощью функции CreateCompatibleBitmap. Выбираем объект с помощью функции SelectObject. Задаем цвет фона, а также рисуем прямоугольник с помощью выбранной кисти. Задаем цвет пера при помощи функции CreatePen. Помещаем дескриптор пера в регистр eax и выбираем объект. Помещаем в offsetY максимальную высоту, видимую на экране. Аналогичные действия проделываем и с осью Ох. Рисуем горизонтальную и вертикульную оси координат. Создаем перо и выбираем цвет.

Помещаем в ScaleX и ScaleY значения (width-16)/4 и (height-54)/2. Это необходимо для более пропорционального расположения графика в окне. Помещаем в ecx 360, на метке L загружаем ecx в стек. Помещаем в cons 5. Загружаем последовательно в стек t и PI. Перемножаем их и делим на deg_rad, в которой хранится значение 180. Загружаем в стек cons и перемножаем st(0) и st(1). Вычисляем синус. Это sin(5t). Подобные операции проделываем, чтобы получить 3sint. Затем складываем 3sint и sin (5t). Умножаем результат на ScaleX и прибавляем к offsetX. Заносим в стек 2 и умножаем на вычисленное cos(3t), добавляем sint. Умножаем это на ScaleY и прибавляем к offsetY. Уыеличиваем t на единицу. Проводим линию для данных значений X и Y. Выгружаем ecx из стека и сравниваем его с 0. Если равно, то идем на метку М. В противном случае уменьщаем ecx на единицу и переходим снова на метку L. На метке М передаем полученные данные в виртуальное окно и даем команду перерисовки. Задаем цвет фона и букв с помощью функции SetBkColor. Помещаем в eax mess_len. Выводим текст названия функции на экран. Обнуляем eax. Переходим на метку FINISH.

WMPAINT: Перерисовываем окно с помощью функции BeginPaint. Помещаем дескриптор окна в eax. Копируем содержимое виртуального окна в реальное. Заканчиваем перерисовку окна с помощью функции EndPaint. Обнуляем eax. Переходим на метку FINISH.

WMDESTROY: Удаляем контексты окна. При получении сообщения WM_QUIT вызываем функцию PostQuitMessage. Обнуляем eax. Переходим на метку FINISH.

DEFWNDPROC: Вызываем обработчик сообщений по умолчанию.

FINISH: Передаем управление вызывающей функции, завершаем данную функцию.


Текст программы.



.586

.model flat,stdcall 



RGBW    equ 00D4D0C8h	; цвет фона в окне



include win.inc 



.data

	hwnd	    dd 0

    hinst      	dd 0

	TITL		db "Курсовой_Копылов_ПС-116",0

	CLASSNAME  	db 'CLASS32',0

    Message    	MSG <?>

    wc         	WNDCLASS  <?>

	

	hdc			dd 0	

	hPen		dd 0

	memdc		dd 0	

	Height_		dd ?

	Width_		dd ?

	rect_		RECT <>

	ps			PAINTSTRUCT	<?>

	

	messX		db	'X=3sint+sin5t Y=2*cos3t +sint',0

	mess_len 	equ $-messX-1

	

	OffsetX		DD ?

	OffsetY		DD ?

	ScaleX		DD ?

	ScaleY		DD ?

	X			DD 0

	Y			DD 0

	t			DD 0

	cons		DD ?

	deg_rad		DD 180



.code

start proc



	invoke  GetModuleHandle,0

    mov     hinst,eax



    mov wc.style,CS_HREDRAW+CS_VREDRAW+CS_GLOBALCLASS 

    mov wc.lpfnWndProc,offset WNDPROC

    

    mov eax,hinst

	mov wc.hInstance,eax



	invoke	LoadIcon,0,IDI_APPLICATION

    mov		wc.hIcon,eax

    

	invoke	LoadCursor,0,IDC_ARROW

	mov		wc.hCursor,eax

	

	invoke  CreateSolidBrush,RGBW

	mov		wc.hbrBackground,eax

    

    mov		wc.lpszMenuName,0

    mov		wc.lpszClassName,offset CLASSNAME

	invoke	RegisterClass, offset wc



	invoke CreateWindowEx,0,

		offset CLASSNAME,

		offset	TITL,

		WS_CAPTION+WS_SYSMENU+WS_THICKFRAME+WS_GROUP+WS_TABSTOP,

		100,100,

		400,450,

		0,0,HINST,0



     cmp eax,0

     jz  END_LOOP

     	

     mov hwnd,eax

     invoke ShowWindow,hwnd,SW_SHOWNORMAL

	invoke UpdateWindow,hwnd



MSG_LOOP:

	invoke GetMessage,offset Message,0,0,0

	

    cmp eax,0

    je  END_LOOP

    

	invoke TranslateMessage,offset Message

	invoke DispatchMessageA,offset Message

    jmp MSG_LOOP

    

END_LOOP:

	invoke ExitProcess,Message.wParam

	

start endp



WNDPROC  proc hW:DWORD,Mes:DWORD,wParam:DWORD,lParam:DWORD



	cmp Mes, WM_DESTROY

	je  WMDESTROY

	     

	cmp Mes, WM_CREATE	

	je  WMCREATE

	     

	cmp Mes, WM_PAINT	

	je  WMPAINT

	     

	cmp Mes,WM_SIZE	 

	je  WMSIZE



	jmp DEFWNDPROC



WMSIZE:

	cmp memdc,0

	jne WMCREATE

	

	invoke DeleteDC,memdc

	

WMCREATE:

	invoke GetDC,hW

	mov hdc,eax

	

	invoke CreateCompatibleDC,hdc

	mov memdc,eax

	

	invoke GetWindowRect,hW,offset rect_

	

	mov eax,rect_.bottom

	sub eax,rect_.top

	mov Height_, eax

	

	mov eax, rect_.right

	sub eax, rect_.left

	mov Width_, eax



	invoke CreateCompatibleBitmap,hdc,Width_,Height_

	invoke SelectObject,memdc,eax

	

	invoke CreateSolidBrush,RGBW

	invoke SelectObject,memdc,eax

	

	invoke PatBlt,memdc,0,0,Width_,Height_,PATCOPY

	invoke ReleaseDC,hW,hdc



	invoke CreatePen,PS_SOLID,2,0

	mov hPen,eax

	invoke SelectObject,memdc,hPen

	

	mov eax,Height_

	sub eax,27

	shr eax,1	

	mov OffsetY,eax

	

	mov eax,Width_

	sub eax,10

	shr eax,1

	mov OffsetX,eax

	

	invoke MoveToEx,memdc,0,OffsetY,0

	invoke LineTo,memdc,Width_,OffsetY

	;;;;;;;;;;;;;;;;;;

	invoke MoveToEx,memdc,OffsetX,0,0

	invoke LineTo,memdc,OffsetX,Height_

	

	invoke CreatePen,PS_SOLID,2,00000000h

	mov hPen,eax

	invoke SelectObject,memdc,hPen

	

	mov		eax,0

	mov		t,eax

	mov		eax, 27

	mov		cons,eax

	fild	Width_

	fisub	cons

	mov		eax, 10

	mov		cons,eax

	fidiv	cons

	fstp	ScaleX



	mov		eax, 27

	mov		cons, eax

	fild	Height_

	fisub	cons

	mov		eax, 10

	mov		cons, eax

	fidiv	cons

	fstp	ScaleY



mov		cons,5

	fild	t

	fldpi

	fmulp

	fidiv	deg_rad

	fild	cons

	fmulp

	fsin                      

                              ;MyX=3sint+sin5t

	fild t

	fldpi

	fmulp

	

	fidiv deg_rad

	fsin

	mov		cons,3

	fild	cons

	fmulp

	

	fadd

	fchs

	fmul	ScaleX

	fiadd	OffsetX

	fistp	X

	

	mov cons,3   

	fild	t

	fldpi

	fmulp

	fidiv	deg_rad

	fild	cons

	fmulp

	fcos





	mov cons,2   	

fild	cons

fmulp

	

	fild t ;sint OK

	fldpi           ;MyX=2cos3t +sint

	fmulp

	fidiv deg_rad

	fsin

	fadd

	

	fmul	ScaleY

	fiadd	OffsetY	

	fistp	Y



invoke MoveToEx,memdc,x,y,0









	mov ecx, 360

L:	push ecx



	mov		cons,5

	fild	t

	fldpi

	fmulp

	fidiv	deg_rad

	fild	cons

	fmulp

	fsin                      

                              ;MyX=3sint+sin5t

	fild t

	fldpi

	fmulp

	

	fidiv deg_rad

	fsin

	mov		cons,3

	fild	cons

	fmulp

	

	fadd

	fchs

	fmul	ScaleX

	fiadd	OffsetX

	fistp	X

	

	mov cons,3   

	fild	t

	fldpi

	fmulp

	fidiv	deg_rad

	fild	cons

	fmulp

	fcos





	mov cons,2   	

fild	cons

fmulp



	

	fild t ;sint OK

	fldpi           ;MyX=2 *cos3t +sint

	fmulp

	fidiv deg_rad

	fsin

	fadd

	

	fmul	ScaleY

	fiadd	OffsetY	

	fistp	Y

	

	inc t

	

	invoke LineTo,memdc,X,Y

	pop ecx

	cmp ecx,0

	je M

	dec ecx

	jmp L



M:

	invoke InvalidateRect,hW,offset rect_,0

	invoke SetBkColor,memdc,RGBW

	

	mov eax, mess_len

	INVOKE TextOutA, memdc, 10, 20, 

	offset messX, eax	; вывод текста X=3cost+cos5t Y=log2(e)*cos3t +sint

    MOV EAX, 0



    JMP FINISH



WMPAINT:

	invoke BeginPaint,hW,offset ps

	mov	hdc,eax

	

	invoke BitBlt,hdc,0,0,Width_,Height_,memdc,0,0,SRCCOPY



	invoke EndPaint,hdc,offset ps

	

	mov eax,0

    jmp FINISH



WMDESTROY:

	invoke DeleteDC,hPen

	invoke DeleteDC,memdc

	invoke PostQuitMessage, 0

    mov eax, 0

    jmp FINISH



DEFWNDPROC:

	invoke DefWindowProc,hW,Mes,wParam,lParam	

     	

FINISH:

	ret 

	WNDPROC endp

	

end START


Процедура WNDProc



Главная функция.



Полученный график полностью совпадает с тем, что получен в программе GraphCalc. Следовательно, моя программа работает верно.