Рисование в SVGA

Пикселы расположены линейно в памяти видеоадаптера. В 256-цветных режимах пиксел представляется одним байтом. Поэтому смещение точки с координатами (x,y) можно вычислить как 640*y+x в режиме с 640 пикселами по горизонтали. Единственное ограничение, связанное с такими вычисленими, — это то, что последний доступный пиксел, к которому может быть получен доступ, имеет координаты x=255, y=102, его смещение 65535. Это известное ограничение 64Kбайтных сегментов.

Чтобы обойти это ограничение, применяется переключение банков памяти. При этом переопределяется расположение физического адреса, которое соответствует логическому адресу. Так, логический адрес 0 соответствует физическому адресу 65536 если активен первый банк в видеодаптером с размером «окна» (granularity) 64 KB.

Логический адрес точки с координатами (x,y) определяется как 640*y+x-B*WG где B — номер банка и WG — размер «окна». Банк памяти может быть переключен с помощью функции AX=4F05h прерывания 10h в видеоадаптерах, поддерживающих стандарт VESA.

Следующая процедура рисует пиксел на экране. Координаты пиксела находятся в регистрах AX и BX, а в регистре CX передается цвет пиксела. В процедуре предполагается, что размер «окна» равен 64 KB, что справедливо, например, для чипов S3.

SVGA_bank dw 0 ;номер активного банка памяти
S_rivi dw 640 ;длина строки в байтах
VGA_seg dw 0A000h ;сегмент памяти экрана VGA
CBpxl$ proc ;рисует пиксел с координатами x=AX, y=BX, цвет=CX
xchg AX,BX ;теперь x=BX, y=AX
mul S_rivi
add AX,BX
adc DX,0 ;в DX помещается требуемый номер банка
mov DI,AX ;логический адрес
cmp DX,SVGA_bank ;банк корректен?
je Cxl256_OK
mov SVGA_bank,DX ;новый банк
mov AX,4F05h
xor BX,BX ;функция: устанавливаем банк DX, окно A
int 10h
Cxl256_OK:
mov BX,ES ;сохраняем сегмент
mov AL,CL ;цвет
mov ES,VGA_seg
stosb ;рисуем пиксел
mov ES,BX
ret
CBpxl$ endp

Реклама

TSR: Завершаемся и остаемся в памяти

Инсталляция TSR-программы выполняется в три этапа:
Загрузка резидентной части в память. Проверка, не находится ли наша программа уже в памяти. Сохранение необходимой информации для дальнейшего удаления резидента из памяти. Освобождение памяти, занятой копией переменных окружения для экономии.
Установка параметров для работы резидентной части. Обычно на этом этапе перехватываются прерывания.
Завершение установочной программы, при этом резидентная часть остается в памяти.
;Структура программы TSR
Begin: ;Здесь начинается .COM-программа
jmp Install
;Сюда нужно поместить резидентную часть

Install:
;сюда поместите код установки
mov AH,31h ;завершиться и остаться резидентом
mov AL,0 ;возвращает результат =OK
mov DX,offset Install
mov CL,4
shr DX,CL ;делим на 16
add DX,1 ;объем резидентной части программы
int 21h

Asm: Чтение значения счетчика времени

В памяти по адресу 40:6C расположено двойное слово, которое увеличивается на единицу приблизительно 18.2 раза в секунду. Системное время можно получить, считывая это слово. Младший байт может быть использован для многих «временных» задач, в т.ч. в качестве исходного значения для генератора псевдослучайных чисел (а в некторых случаях и заменить его).

GetTicks proc ;POW37
; Входные данные: нет
; Выходные данные: Младший байт счетчика времени в AX
; Регистры не сохраняются.
mov BX,ES ;Сохраняем адрес дополнительного сегмента
mov AX,40h ;сегмент данных BIOS
mov ES,AX
mov AX,ES:[6Ch] ;читаем счетчик
mov ES,BX ;восстанавливаем регистр ES
ret
GetTicks endp

Ассемблер сопроцессор: Вычислить 6 значений функции: Yn = 4x/(x + 5) (х изменяется от 3 с шагом 1,25). Результат округлить к целому, разместить в памяти и вывести на экран.

Вычислить 6 значений функции: Yn = 4x/(x + 5) (х изменяется от 3 с шагом 1,25). Результат округлить к целому, разместить в памяти и вывести на экран.

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

.386 ; директива определения типа микропроцессора
.model flat,stdcall ; задание линейной модели памяти
option casemap:none ; отличие малых и больших букв
include \masm32\include\windows.inc
include \masm32\include\kernel32.inc
include \masm32\include\fpu.inc
include \masm32\include\user32.inc

includelib \masm32\lib\user32.lib
includelib \masm32\lib\kernel32.lib
includelib \masm32\lib\fpu.lib

.data ; директива определения данные

_x dd 3 ; сохранение в 32-разрядном амбарчике памяти переменной х
_y dd 0 ; резервирование 32-х разрядов памяти для переменной в
tmp1 dd ? ; резервирование 32-х разрядов памяти для переменной tmp1
tmp2 dd ? ; резервирование 32-х разрядов памяти для переменной tmp2
hod dd 1.25
krok dd 5
_umnoj dd 4 ; умножение на 4
probel dd 09h ; для вывода на экран
res dd 0
ifmt db «Yn = %d»,0
st1 db «Yn = 4x/(x + 5) «,0
st2 dd 10 dup(?),0
st3 dd 10 dup(?),0

.code ; директива начала кода программы
_start: ; директива начала кода программы
lea edi,st2
lea esi,st3
xor eax,eax ; обнуление регистров
xor ebx,ebx
xor ecx,ecx
xor edx,edx
finit ; инициирующее сопроцессора
mov ecx,6
fild _x
m1:
fld st(0)
fiadd krok
fld st(1)
fimul _umnoj
fmul st(0),st(1)
fistp dword ptr [edi] fistp dword ptr [esi] fadd hod

add edi,4

loop m1

lea edi,st2
mov eax[edi+20]

invoke wsprintf \
ADDR st2 \
ADDR ifmt \
eax
invoke MessageBox \
NULL \
addr st2 \
addr st1 \
MB_OK
invoke ExitProcess,0
end _start ; зак?нчення программы

1.2 Результат работы программы

Написать программу на Ассемблере вычисления выражений: b/c + ас. Результат вычисления выражения сохранить в памяти. Навести значение и порядок размещения данные в памяти.

.386 ; директива определения команд микропроцессора

.model flat,stdcall ; задание линейной модели памяти
; но соглашения ОС Windows
option casemap:none ; отличие строчных и прописных букв
includelib\masm32\lib\kernel32.lib
ExitProcess proto :DWORD
ADDDD proto :WORD, :WORD, :WORD ; прототип процедуры
.data ; директива определения данные
res dw 2 dup(0) ; резервирование амбарчиков для результата
.code ; директива начала кода программы
start: ; метка начала программы с именем start
invoke AddDD,5,86,1986 ; вызов директивы AddDD с параметрами
invoke ExitProcess,0
ADDDD proc arg1:WORD,arg2:WORD,arg3:WORD
mov eax,0 ; очистка регистров
mov ebx,0
mov ecx,0
mov edx,0

mov ах,arg3 ; arg3 = 1986
div arg2 ; операция деления
mov bx,ax
mov cx,dx

mov ах,arg1 ; ах := arg1
mul arg2 ; ax* arg2 = 86
SHL edx,16 ; операция здвигу
mov dx,ax

add ebx,edx
mov res,cx ; запоминание в памяти
mov res+2,dx ; запоминание в памяти
ret ; возвращение из процедуры
AddDD endp ; окончание процедуры с именем AddDD
end start ; окончание программы с именем start

Вывод данных в файл: для функции Y = 40Х + 10 получить первое значение, превышающей 512, начиная с Х = 1. Значение аргумента и функции записать в ячейки памяти.

.386 ;директива определения типа микропроцессора

. Model flat, stdcall ; задачи линейной модели памяти
; И соглашения ОС Windows
option casemap: none; отличие малых и больших букв

include \masm32\include\windows.inc
include \masm32\include\kernel32.inc
includelib \masm32\lib\user32.lib
includelib \masm32\lib\kernel32.lib

BSIZE equ 40; количество байтов, которые записываются в файл
. Data; директива определения данных
fName BYTE «info_file.txt», 0; ячейки для файла
fHandle DWORD? ; Резервирования в памяти 32-разрядной
;ячейки с именем fHandle для дескриптора сохранения файлов
cWritten DWORD? ; Резервирования 32-разрядной ячейки памяти
; С именем cWritten для адреса символов вывода
st1 db ‘Аргумент =’, 0
st1_kol = $ — st1
st2 db ‘Значение функции =’, 0
st2_kol = $ — st2
st3 db 100 dup (0)
stemp db 3 dup (0)
stemp2 db 3 dup (0)
ifmt db «% d», 0
_x dw 1
_y dw 0
const40 dw 40
const10 dw 10
temp db 15
prom db 0

. Code; директива начала сегмента-данных
start:; метка начала программы с именем start

mov eax, 0
mov ebx, 0
mov ecx, 0
mov edx, 0

lea edi, st3
lea esi, st1
mov ecx, st1_kol
m1:
mov al, [esi] mov [edi], al
inc esi
inc edi
loop m1

m2:
mov ax, _x
mul const40
add ax, const10
mov _y, ax
. IF (_y> 512)
jmp _end
. ELSE
inc _x
jmp m2
. ENDIF
_end:
mov eax, 0
mov ax, _x

invoke wsprintf, \; API-функция преобразования числа
ADDR stemp, \; адрес буфф, куда будет записана помет. символов
ADDR ifmt, \; адрес строки преобразования формата
eax; регистр, содержимое которого превращается

lea esi, stemp
mov ecx, 3
dec edi
z1:
mov al, [esi] mov [edi], al
inc edi
inc esi
loop z1
mov al, 10
mov [edi], al
inc edi
mov al, 13
mov [edi], al
inc edi

lea esi, st2
mov ecx, st2_kol
m3:
mov al, [esi] mov [edi], al
inc esi
inc edi
loop m3
dec edi

mov eax, 0
mov ax, _y
invoke wsprintf, \; API-функция преобразования числа
ADDR stemp2, \; адрес буфф, куда будет записана помет.символов
ADDR ifmt, \; адрес строки преобразования формата
eax; регистр, содержимое которого превращается
lea esi, stemp2
mov ecx, 6
dec esi
z2:
mov al, [esi] mov [edi], al
inc edi
inc esi
loop z2

invoke CreateFile, ADDR fName,; адрес имени файла с символами
GENERIC_WRITE, \; запись в файл
0, NULL,; параметры многозадачности
CREATE_ALWAYS,; уничтожить и создать новый файл
FILE_ATTRIBUTE_ARCHIVE, 0

mov fHandle, eax; программирование дескриптора устройства
invoke WriteFile, fHandle,; дескриптор устройства
ADDR st3,;адрес области памяти,сохраняющий символы
BSIZE,, Количество символов
ADDR cWritten,; адрес памяти,где хранится число
NULL; записанных в файл символ_в
invoke CloseHandle,fHandle; дескриптор файла
invoke ExitProcess,0 ; возврат управления Windows
; И освобождения ресурсов
end start; директива окончания программы с именем start