Графика и ассемблер – насколько это совместимо - Студенческий научный форум

XII Международная студенческая научная конференция Студенческий научный форум - 2020

Графика и ассемблер – насколько это совместимо

Руссу Ю.Д. 1, Абрамова О.Ф. 1
1ВПИ (филиал) ВолгГТУ
 Комментарии
Текст работы размещён без изображений и формул.
Полная версия работы доступна во вкладке "Файлы работы" в формате PDF

На данный момент существует огромное количество различных редакторов, программ или мобильных приложений, позволяющих взаимодействовать с графикой. Как правило, разрабатываются они для различных целей и пишутся на совершенно разных языках программирования. Столь огромный спектр различных редакторов ставит перед разработчиком выбор наиболее подходящей для конкретной задачи среды программирования для создания и обработки графики. Все языки программирования во многом отличаются друг от друга, а, значит, каждый из них имеет как свои преимущества в плане графики, так и недостатки. В этой статье рассмотрим графику на языке ассемблера.

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

К примеру, рассмотрим программу, позволяющую нарисовать на экране окружность.

.model tiny

.code

ORG 100h

RADIUS EQU 30 ;рисуем окружность с радиусом 30

RADIUS2 EQU RADIUS*RADIUS ;квадратрадиуса

DIAMETR EQU RADIUS*2 ;диаметр окружности

N EQU 157*RADIUS/200 ;количество точек на 1/8

COLOR EQU 10 ;цвет окружности

start: MOV AH,0Fh ;узнать номер текущего видеорежима

INT 10h

MOV VIDEOR,AL ;запомним текущий видеорежим

MOV AX,13h ;установить видеорежим 320х200х256

INT 10h

PUSH 0A000h ;установить регистр ES на сегмент

POP ES ; видеопамяти

XOR BP,BP ;будем увеличивать X и Y

MOV Y,RADIUS-1 ;координаты X=0 и Y=R

CALL DRAW_OCT1 ;рисуем восьмушку окружности

MOV BP,RADIUS-1 ;координата X=2*R

MOV Y,0 ;координата Y=0

CALL DRAW_OCT2 ;рисуем восьмушку окружности

NEG DELTA_X ;увеличиваем Y и уменьшаем X

MOV Y,RADIUS

MOV BP,DIAMETR ;координаты Y=R и X=2*R

CALL DRAW_OCT1 ;рисуем восьмушку окружности

MOV BP,RADIUS ;координата X=R

MOV Y,0 ;координата Y=0

CALL DRAW_OCT2 ;рисуем восьмушку окружности

NEG DELTA_Y ;уменьшаем координаты Y и X

MOV Y,RADIUS ;координата Y=R

MOV BP,DIAMETR ;координата X=2*R

CALL DRAW_OCT1 ;рисуем восьмушку окружности

MOV BP,RADIUS ;координата X=R

MOV Y,DIAMETR ;координата Y=2*R

CALL DRAW_OCT2 ;рисуем восьмушку окружности

NEG DELTA_X ;уменьшаем Y и увеличиваем X

XOR BP,BP ;координата X=0

MOV Y,RADIUS ;координата Y=R

CALL DRAW_OCT1 ;рисуем восьмушку окружности

MOV BP,RADIUS ;координата X=R

MOV Y,DIAMETR ;координата Y=2*R

CALL DRAW_OCT2 ;рисуем восьмушку окружности

XOR AX,AX ;ожидание нажатия любой клавиши

INT 16h

MOV AX,WORD PTR VIDEOR ;восстановление видеорежима

INT 10h

RET ;выход из программы

DELTA_CALC PROC ;рассчитаем ошибку накопления

MOV BX,AX ;в AX значение координаты X или Y

DEC AX ;вычислим (Y+0,5)2 Y2+Y

MUL AX ;или (X+0,5)2 X2+X

ADD AX,BX

MOV DELTA,AX ;и поместим это значение в DELTA

RET

DELTA_CALC ENDP

;процедура прорисовки 1/8 окружности с вычислением

DRAW_OCT1 PROC ; координаты X

MOV AX,Y

SHL AX,6 ;должно быть DI=Y*320, но для умножения

MOV DI,AX ;на 320 используем сдвиги, AX= Y*64,

SHL AX,2 ;сохраним AX в DI и умножим Y*64 на 4

ADD DI,AX ;DI=Y*(256+64)=Y*320.

MOV AX,BP

SUB AX,RADIUS ;BP=X AX=R-X

CALL DELTA_CALC ;расчет ошибки накопления по X

MOV CX,N

CIRC1: MOV AX,Y

SUB AX,RADIUS ;AX=Y-R

MUL AX

NEG AX

ADD AX,RADIUS2 ;AX=R2-Y2

CMP DELTA,AX ;сравнить текущий X2=R2-Y2 с ошибкой

JBE A3 ;накопления, если меньше, увеличиваем или

ADD BP,DELTA_X ;уменьшаем только Y, иначе

MOV AX,BP ;увеличиваем или уменьшаем еще и X и

SUB AX,RADIUS ;вычисляем новую ошибку накопления

CALL DELTA_CALC

A3: CMP DELTA_Y,1

JNE A1

ADD DI,320

JMP SHORT A2

A1: SUB DI,320

A2: MOV BYTE PTR ES:[DI][BP],COLOR ;выводимточкуна

MOV AX,DELTA_Y ; экран

ADD Y,AX

LOOP CIRC1 ;повторяемцикл

RET

DRAW_OCT1 ENDP

;процедура прорисовки 1/8 окружности с вычислением

DRAW_OCT2 PROC ;координаты X

MOV AX,Y

SHL AX,6 ;должно быть DI=Y*320, но для умножения

MOV DI,AX ;на 320 используем сдвиги, AX= Y*64,

SHL AX,2 ;сохраним AX в DI и умножим Y*64 на 4

ADD DI,AX ;DI=Y*(256+64)=Y*320.

MOV AX, Y

SUB AX,RADIUS

CALL DELTA_CALC

MOV CX,N

CIRC2: MOV AX,BP

SUB AX,RADIUS

MUL AX

NEG AX

ADD AX,RADIUS2 ;AX=R2-(X-R)2

CMP DELTA,AX

JBE A5

MOV AX,DELTA_Y

ADD Y,AX

MOV AX,Y

SUB AX,RADIUS

CALL DELTA_CALC

CMP DELTA_Y,1

JNE A4

ADD DI,320

JMP SHORT A5

A4: SUB DI,320

A5: ADD BP,DELTA_X

MOV BYTE PTR ES:[DI][BP],COLOR

LOOP CIRC2

RET

DRAW_OCT2 ENDP

VIDEOR DB 0,0 ;значение текущего видеорежима

DELTA DW 0 ;ошибка накопления

DELTA_X DW 1 ;смещение по оси X

DELTA_Y DW 1 ;смещение по оси Y

Y DW 0 ;координата Y

END start

На языке C++ окружность можно нарисовать так:

#include <windows.h>

int main()

{

HWND handle = FindWindowA("ConsoleWindowClass", NULL);

HDC hdc = GetDC(handle);

// Создаёмперо (контур)

HPEN hPen = CreatePen(PS_SOLID, 1, RGB(0, 255, 72));

// Создаёмкисть (заливка)

HBRUSH hBrush = CreateSolidBrush(RGB(12, 12, 12));

SelectObject(hdc, hPen); // Указываемперо

SelectObject(hdc, hBrush); // Указываемкисть

int radius = 30; // Радиусокружности

// Верхний левый угол описывающего прямоугольника

int leftX = 0, leftY = 65;

// Нижний правый угол описывающего прямоугольника

int rightX = leftX + 2 * radius, rightY = leftY + 2 * radius;

Ellipse(hdc, leftX, leftY, rightX, rightY); // Рисуемокружность

return 0;

}

Как видно из примера, нарисовать даже простейший графический примитив на чистом ассемблере сложно. Изобразить ту же окружность можно при помощи стороннего API, однако нужно ли в таком случае использовать для этого ассемблер?

Обобщая вышесказанное, можно сказать, что ассемблер действительно позволяет разработчику взаимодействовать с графикой, однако создать что-то действительно стоящее и, самое главное, отвечающее современным требованиям на этом языке очень непросто. Ассемблер позволяет оптимизировать процесс, например, вычислений для отрисовки графики, созданной на специально разработанном для этих целей языке. То есть язык ассемблера в полной мере раскрывает свой потенциал именно в комбинации с другими, более высокоуровневыми языками программирования.

Библиографический список

Создание графических примитивов на Ассемблере [Электронный ресурс] // URL: https://habr.com/post/134495/

Абрамова О.Ф. Компьютерная графика. Избранные лекционные темы. Ч. 1: учеб. пособие / О.Ф. Абрамова. - Saarbrucken, 2012. - 129 с.

Графика на ассемблере [Электронный ресурс] // URL: http://www.chipinfo.ru/literature/chipnews/200007/48.html

Абрамова О.Ф. Компьютерная графика : лабораторный практикум [Электронный ресурс]: учеб. пособие / О.Ф. Абрамова, Д.Н. Лясин; ВПИ (филиал) ВолгГТУ. - Волгоград, 2017. - 1 электрон. опт. диск (CD-ROM). - 74 с.

Абрамова О.Ф. Компьютерная графика : конспект лекций для студентов направлений 230100.62 «Информатика и вычислительная техника» и 231000.62 «Программная инженерия» [Электронный ресурс]: учеб. пособие / О.Ф. Абрамова; ВПИ (филиал) ВолгГТУ // Учебные пособия : сб. Серия «Естественнонаучные и технические дисциплины». Вып. 3. - 1 электрон. опт. диск (CD-ROM) ; формат pdf. - Волжский, 2012. - 165 с.

Просмотров работы: 230