- •Введение Основные определения
- •Системы счисления Основные определения
- •Двоичная, восьмеричная и шестнадцатеричная системы счисления
- •Смешанные системы счисления
- •Перевод чисел из одной системы счисления в другую
- •Арифметические действия в системах счисления с основанием, отличным от 10
- •Двоично-восьмеричные и двоично-шестнадцатеричные преобразования
- •Обратный и дополнительный коды и их применение в операциях с отрицательными числами
- •Сложение и вычитание чисел со знаком в дополнительном коде
- •Архитектура персонального компьютера История развития вычислительной техники
- •Основные термины и определения
- •Функциональная структура компьютера
- •Архитектура микропроцессора
- •Регистры общего назначения и сегментные регистры
- •Управляющие регистры Регистр cr0.
- •Память компьютера
- •Структура программы на языке Ассемблера Формат кодирования в языке Ассемблера
- •Структура программы на ассемблере
- •Простейшая программа в ос Windows
- •Типы и форматы данных в ассемблере
- •Базовая система команд микропроцессора ia-32
- •Операнды языка ассемблер
- •Стандартные директивы сегментации
- •Макрокоманды
- •Процедуры (функции)
- •Организация интерфейса с процедурой
- •Возврат результата из процедуры
- •Связь ассемблера с языками высокого уровня
- •Обработка прерываний
- •Создание исполняемого файла
- •Отладка программы
- •Математический сопроцессор
- •Представление чисел с плавающей точкой в разрядной сетке вычислительной машины
- •Архитектура сопроцессора
- •Система команд сопроцессора
- •Команды передачи данных
- •Команды загрузки констант
- •Команды сравнения данных
- •Арифметические команды
- •Команды управления математическим сопроцессором
- •Пример программы с использованием команд сопроцессора
- •Сложные типы данных Структуры
- •Объединения
- •Программирование для windows
- •Основы программирования в ос Windows
- •Консольные приложения Windows
- •Работа с файлами в системе Windows
- •Вывод чисел в консоль
- •Оконные (каркасные) приложения Windows
- •Графика в оконных приложениях Windows
- •Ресурсы в Windows-приложениях
- •Приложение 1
Графика в оконных приложениях Windows
Система координат для вывода графических образов такая же, как и для ввода текстовой информации. Координаты измеряются в логических единицах, которые по умолчанию совпадают с пикселями. Начало отсчета – верхний левый угол окна.
Для создания графических образов используются 3 основных объекта: точка (пиксел), перо, кисть.
Цвет точки задается с помощью функции
COLORREF SetPixel(
HDC hdc, // дескриптор контекста окна
int X, // x-координата точки
int Y, // y-координата точки
COLORREF crColor); // цвет точки
Перо используется для рисования линий и контуров замкнутых фигур. Цвет пера задается при помощи функции
HPEN CreatePen(
int fnPenStyle, // стиль пера
// PS_SOLID =0
// PS_DASH =1
// PS_DOT =2
// PS_DASHDOT =3
// PS_DASHDOTDOT =4
// PS_NULL =5 невидимое перо
int nWidth, // ширина пера
COLORREF crColor); // цвет пера
Кисть используется для закрашивания замкнутых объектов. Цвет кисти задается с помощью функции
HBRUSH CreateSolidBrush( COLORREF crColor ); // цвет кисти
Можно заранее создать несколько кистей и перьев, а затем выбирать нужные с помощью функции
HGDIOBJ SelectObject(
HDC hdc, // дескриптор контекста окна
HGDIOBJ hgdiobj ); // дескриптор объекта
Обновление информации в окне программы происходит по получению сообщения WM_PAINT. В реальных программах вывод информации в окно может происходить по различным событиям и из различных процедур. Кроме того, если информации в окне много, то непосредственный вывод при помощи функции TextOut достаточно медленный. Чтобы воспроизводить содержимое окна, необходимо где-то запомнить это содержимое. Возникает проблема сохранения информации (и не только текстовой), находящейся в окне.
В операционной системе Windows образуется виртуальное окно, и весь вывод информации производится туда. Затем по приходе сообщения WM_PAINT содержимое виртуального окна копируется на реальное окно. В целом общая схема такова:
1. При создании окна
создается совместимый контекст устройства функцией
HDC CreateCompatibleDC( HDC hdc); // дескриптор контекста окна
Полученный контекст следует запомнить.
создается карта бит, совместимая с данным контекстом функцией
HBITMAP CreateCompatibleBitmap(
HDC hdc, // дескриптор контекста окна
int nWidth, // ширина пиксельной картинки
int nHeight ); // высота пиксельной картинки
выбирается кисть цветом, совпадающим с цветом основного окна.
создается битовый шаблон путем выполнения растровой операции с использованием выбранной кисти. Функция перерисовки заданного прямоугольника выбранной кистью
BOOL PatBlt(
HDC hdc, // дескриптор контекста окна
int nXLeft, // x- координата верхнего левого угла
int nYLeft, // y- координата верхнего левого угла
int nWidth, // ширина прямоугольника
int nHeight, // высота прямоугольника
DWORD dwRop); // код растровой операции:
;PATCOPY =0F00021h копирует цвет кисти в окно.
;PATINVERT =5A0049h комбинирует цвет кисти и цвет окна функцией XOR
;DSTINVERT =550009h инвертирует цвет прямоугольника
;BLACKNESS =42h закрашивает прямоугольник черным цветом
;WHITENESS =0FF0062h закрашивает прямоугольник белым цветом
Вся информация выводится в виртуальное окно и дается команда перерисовки окна. Функция
BOOL InvalidateRect(
HWND hWnd, // дескриптор окна
CONST RECT* lpRect, // координаты прямоугольника
BOOL bErase); // при 1 фон стирается, при 0 остается
RECT STRUCT
left dd ?
top dd ?
right dd ?
bottom dd ?
RECT ENDS
При получении сообщения WM_PAINT содержимое виртуального окна копируется на реальное окно. Функция
BOOL BitBlt(
HDC hdcDest, // дескриптор совместимого контекста
int nXDest, // x- координата левого верхнего угла совм. контекста
int nYDest, // y- координата левого верхнего угла совм. контекста
int nWidth, // ширина прямоугольника совместимого контекста
int nHeight, // высота прямоугольника совместимого контекста
HDC hdcSrc, // дескриптор контекста окна
int nXSrc, // x- координата левого верхнего угла контекста окна
int nYSrc, // y- координата левого верхнего угла контекста окна
DWORD dwRop); // код растровой операции
SRCCOPY equ 0CC0020h
SRCPAINT equ 0EE0086h
SRCAND equ 8800C6h
SRCINVERT equ 660046h
SRCERASE equ 440328h
Для рисования можно использовать следующие функции API:
BOOL LineTo( // провести прямую линию выбранным пером
// от текущей точки до указанной точки
HDC hdc, // дескриптор контекста окна
int nXEnd, // x- координата конечной точки
int nYEnd); // y- координата конечной точки
BOOL MoveToEx( // переместить текущую точку
HDC hdc, // дескриптор контекста окна
int X, // x- координата новой текущей точки
int Y, // y- координата новой текущей точки
LPPOINT lpPoint); // указатель на структуру POINT, куда
// поместятся координаты старой текущей точки, может быть равен 0
BOOL ArcTo( // рисование дуги
HDC hdc, // дескриптор контекста окна
int nLeftRect, // x-координата верхнего левого угла
int nTopRect, // y- координата верхнего левого угла
int nRightRect, // x- координата нижнего правого угла
int nBottomRect, // y- координата нижнего правого угла
int nXRadial1, // x- координата конца первого радиуса
int nYRadial1, // y- координата конца первого радиуса
int nXRadial2, // x- координата конца второго радиуса
int nYRadial2); // y- координата конца второго радиуса
BOOL Rectangle( // рисование прямоугольника
HDC hdc, // дескриптор контекста окна
int nLeftRect, // x-координата верхнего левого угла
int nTopRect, // y-координата верхнего левого угла
int nRightRect, // x-координата нижнего правого угла
int nBottomRect); // координата нижнего правого угла
BOOL Ellipse( // рисование эллипса
HDC hdc, // дескриптор контекста окна
int nLeftRect, // x- координата верхнего левого угла
int nTopRect, // y- координата верхнего левого угла
int nRightRect, // x- координата нижнего правого угла
int nBottomRect); // y- координата нижнего правого угла
Для получения размера окна при его изменении используется функция
BOOL GetWindowRect( HWND hWnd, // дескриптор окна
LPRECT lpRect); // указатель на структуру RECT
Для освобождения контекста окна используется функция
int ReleaseDC(
HWND hWnd, // дескриптор окна
HDC hDC); // дескриптор контекста окна
Для удаления контекста окна используется функция
BOOL DeleteDC( HDC hdc ); // дескриптор контекста окна
Для получения сведений о размерах (в пикселях) элементов окна системы используется функция
int WINAPI GetSystemMetrics( __in int nIndex)
nIndex – константа, определяющая необходимую величину для измерений
SM_CXSCREEN=0 каличество точек экрана по горизонтали
SM_CYSCREEN=1 каличество точек экрана по вертикали
SM_CYCAPTION=4 высота строки заголовка
SM_CXFRAME =32 толшина вертикальной рамки окна
SM_CYFRAME =8 толшина горизонтальной рамки окна
Пример: вывести график функции y=sin(t) при t[0,3600].
Вывод точек осуществляется функцией LineTo. Значение координат точек вычисляется по формулам:
X=OffsetX + tScaleX, Y=OffsetY + yScaleY, (*)
где OffsetX, OffsetY – смещения начала отсчета графика относительно начала отсчета окна;
ScaleX, ScaleY – масштабные коэффициенты осей.
Если принять, что данные, возвращаемые функцией GetWindowRect, позволяют вычислить ширину окна Width и высоту окна Height2, то величины в формулах (*) можно определить как
OffsetX = 0, OffsetY = Height/2,
ScaleX = Width/360, ScaleY = 1/(Height/2)=2/Height
; текст программы
.586
.MODEL FLAT, stdcall
RGBW equ 00D4D0C8h ; цвет фона в окне
include win.inc3
.data
HWND DD 0 ; дескриптор главного окна
HINST DD 0 ; дескриптор приложения
TITL DB "Программа",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 'y=sin(t)',0
mess_len equ $-messX-1
OffsetX DD 0
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, ; X — координата левого верхнего угла
100, ; Y — координата левого верхнего угла
400, ; DX - ширина окна
450, ; DY — высота окна
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, 0,0 ; черное перо
mov hPen, eax
INVOKE SelectObject, memdc, hPen
mov eax, Height_
sub eax, 27
shr eax, 1
mov OffsetY, eax
INVOKE MoveToEx, memdc, 0, OffsetY, 0 ; горизонтальная ось
INVOKE LineTo, memdc, Width_, OffsetY
INVOKE CreatePen, PS_SOLID, 2, 000000FFh ; красное перо
mov hPen, eax
INVOKE SelectObject, memdc, hPen
INVOKE MoveToEx, memdc, 0, OffsetY, 0
mov eax, 0
mov t, eax
mov eax, 8 ; GetSystemMetrics(SM_CXFRAME)*2
mov cons, eax
fild Width_
fisub cons
fidiv deg_rad
mov eax, 2
mov cons, eax
fidiv cons
fstp ScaleX
mov eax, 27 ; GetSystemMetrics(SM_CYFRAME)*2 +
mov cons, eax ; GetSystemMetrics(SM_CXFRAME)*2
fild Height_
fisub cons
mov eax, 2
mov cons, eax
fidiv cons
fstp ScaleY
mov ecx, 360
L: push ecx
fild t
fmul ScaleX
fiadd OffsetX
fistp X
fild t
fldpi
fmulp
fidiv deg_rad
fsin
fchs
fmul ScaleY
fiadd OffsetY
fistp Y
inc t
INVOKE LineTo, memdc, X, Y
pop ecx
loop L
INVOKE InvalidateRect, hW, offset rect_,0
INVOKE SetBkColor, memdc, RGBW
mov eax, mess_len
INVOKE TextOutA, memdc, 10, 20,
offset messX, eax ; вывод текста y=sin(t)
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
; обработка сообщения по умолчанию
DEFWNDPROC:
INVOKE DefWindowProc,
hW,
Mes,
wParam,
lParam
JMP FINISH
WMDESTROY:
INVOKE DeleteDC, hPen
INVOKE DeleteDC, memdc
INVOKE PostQuitMessage, 0
MOV EAX, 0
FINISH:
ret
WNDPROC ENDP
END START
Результат работы программы: