График функции по 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. Следовательно, моя программа работает верно.