Линейные преобразования в системах с фиксированной точкой

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

Числа предствалены в 32-битном формате с фиксированной точкой. Старшее слово содержит целую часть числа, а младшее слово — дробную часть. Предполагается, что используются только положительные числа.

Код использует 32-битные инструкции, но может быть откомпилирован и 16-битным компилятором.

; данные
ConvFactor dw 26214 ;младший байт коэффициента преобразования 25.4
dw 25 ;старший байт
Inches dw 32768 ;младший байт представления 12.5 дюймов
dw 12 ;старший байт
mMeters dw ? ;младший байт результата в мм
dw ? ;старший байт
; код
db 66h
mov AX,Inches ;mov EAX,dword ptr ConvFactor
db 66h
mul ConvFactor ;результат в EDX:EAX
mov CL,16
db 66h
shr AX,CL ;shr EAX,16
mov mMeters,AX ;младший байт результата
mov mMeters+2,DX ;старший байт

Реклама

Установка видеорежимов VGA

Видеорежимы, поддерживаемые BIOS’ом адаптеров VGA BIOS:
Экран
Режим Текст Графика Цвета Размер Адрес

0 CGA 25*40 only text 16 B&W 2000 0B800h
1 CGA 25*40 only text 16 2000 0B800h
2 CGA 25*80 only text 16 B&W 4000 0B800h
3 CGA 25*80 only text 16 4000 0B800h
4 CGA 25*40 320*200 4 16000 0B800h
5 CGA 25*40 320*200 2 B&W 8000 0B800h
6 CGA 25*80 640*200 2 16000 0B800h
7 MDA 25*80 only text 2 4000
0Dh EGA 25*40 320*200 16 32000 0A000h
0Eh EGA 25*80 640*200 16 64000 0A000h
0Fh EGA 25*80 640*350 2 28000 0A000h
10h EGA 25*80 640*350 16 112000 0A000h
11h VGA 30*80 640*480 2 38400 0A000h
12h VGA 30*80 640*480 16 153600 0A000h
13h VGA 25*40 320*200 256 64000 0A000h
Требуемый видеорежим устанавливается вызовом функции BIOS

mov AH,0 ;POW39
mov AL,ScreenModeNumber
int 10h

Этот фрагмент также очищает экран. Содержимое AX не сохраняется. Стандартный BIOS не возвращает никакой информации, сигнализирующей об ошибке. В подерживаемых режимах можно читать и писать в видеопамять путем вызовов соответствующих функций (функции 8,9,0Ch,0Dh). Нормальный текстовый режим DOS — это режим 3.

Следующий фрагмент загружает набор символов из ROM в RAM и соответственно корректирует высоту отображения символов.

mov AH,11h ;изменить используемый набор символов и корректировать высоту их отображения
;mov AL,11h ;выбрать набор символов 8*14, 28 строк в режиме VGA
;mov AL,12h ;выбрать набор символов 8*8, 50 строк
mov AL,14h ;выбрать набор символов 8*16, 25 строк
mov BX,0 ;банк памяти генератора символов
int 10h

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

Задано текст из 32 символов, состоящий из слов, разделенных одним пробелом. Определить количество слов и количество согласных букв в каждом слове.

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

. Model flat, stdcall; задачи линейной модели памяти
; И соглашения ОС Windows
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

ExitProcess proto: DWORD
BSIZE equ 30

. Data; директива определения данных
_a dword 3.0; сохранение в 32-разрядной ячейке памяти переменной х
_sum dword 0
sum dword 0
temp_ecx dd 0
mas1 db ‘Privet kak dela u tebya’
mas2 db ‘qwrtpsdfghjklzxcvbnmQWRTPSDFGHJKLZXCVBNM’
st1 db «Вывод количества слов:» 0
st2 db 10 dup (?), 0
ifmt db «Количество слов в тексте =% d. Количество согласных букв =% d», 0

. Code; директива начала кода
_start:
lea edi, mas1
mov ecx, 23
mov edx, 0
kol:
mov al, ‘ ‘
mov ebx, ecx
repne scasb
sub ebx, ecx
. IF (ebx> 2)
inc _sum
. ENDIF
add ecx, 0
jnz kol
lea edi, mas1
mov ecx, 23
m1:
mov al, ‘ ‘
mov bl, [edi] xor al, bl; проверка слова
jz m2
mov temp_ecx, ecx; хранения регистра
mov ecx, 40
lea esi, mas2
mov al, [esi] _S1:
. IF (al == bl); сложная условие
inc sum;подсчет количества согласных букв
jmp _mm1

. ELSE; иначе
inc esi; расчет адреса нового числа
mov al, [esi] loop _S1; перейти, если ecx? 0

. ENDIF
_mm1: mov ecx, temp_ecx ;возврат счетчика
_m1:
cld
inc edi
loop m1
jmp m3

m2:
mov edx, 0
jmp _m1

m3:
mov edx, _sum
mov eax, sum; перемещения числа согласных букв

invoke wsprintf, \
ADDR st2, \
ADDR ifmt, \
edx, eax; вывод содержимого
invoke MessageBox, \
NULL, \
addr st2, \
addr st1 \
MB_OK
invoke ExitProcess, 0
end _start; окончания программы

Задано текст из 30 символов. Сжать текст, оставив между словами по одному пропуску.

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

. Model flat, stdcall; задачи линейной модели памяти
; И соглашения ОС Windows
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

ExitProcess proto: DWORD
BSIZE equ 30

. Data; директива определения данных
_a dword 3.0; сохранение в 32-разрядной ячейке памяти переменной х
_prob dword 0
_sum dd 0

mas1 db ‘Privet kak dela u tebya’
mas2 db 30 dup (0), 0
st1 db «Вывод количества пробелов», 0
st2 db 10 dup (?), 0
ifmt db «Количество лишних пробелов в тексте =% d», 0

. Code;директива начала кода
_start:
lea edi, mas1
lea esi, mas2
mov ecx, 30; счетчик
mov edx, 1
mov ebx, 0

m1:
mov eax, 0
mov al, »
mov bl, [edi] xor al, bl; проверка равенство сроки пробел
jz m2
mov _sum, 0; сумма пробелов равна нулю
_m1: mov edx, 1
mov ax, [edi];Копирование сроки в сроке без лишних
mov [esi], ax; пробелов
inc esi
_m2:
cld
inc edi
loop m1; уменьшения счетчик
jmp m3; безусловный переход на выводок

m2:
inc _sum; инкрементирование
sub edx, _sum; проверка: это первый пробел или нет
jz _m1
mov edx, 1
inc _prob;подсчитывание лишних пробелов
jmp _m2

m3:
mov edx,0
mov edx,_prob

mov ecx,30
lea edi,mas1
mov eax,0

m4:
mov [edi],ax
inc edi
loop m4

lea edi,mas1
lea esi,mas2
mov ecx,30

m5:
mov ax,[Edi]; копирование второй строки в первую
mov [esi],x
inc esi
inc edi
cld
loop m5
invoke wsprintf, \
ADDR st2, \
ADDR ifmt, \
edx
invoke MessageBox, \
NULL, \
addr st2, \
addr st1 \
MB_OK
invoke ExitProcess, 0
end _start; окончания программы

Вычисление с выводом данных в окно консоли: Задано массив А из N = 4 элементов. Написать программу определения суммы элементов массива А, для которых биты 0 и 5 совпадают.

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

. Model flat, stdcall; задачи линейной модели памяти
; И соглашения ОС Windows
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

ExitProcess proto: DWORD

. Data; директива определения данных
st1 db «Вывод суммы массива! А», 0
st2 db 10 dup (?), 0
ifmt db «Сумма =% d», 0
masivA db 75,31,88,32
sum dw 0
iden db 0
work1 db 0
work2 db 0
prom dd 0

. Code; директива начала кода
_start:
mov eax, 0
mov ebx, 0
mov ecx, 3
mov edx, 0
lea esi, masivA

M1:
mov prom, ebx
mov al, byte ptr [esi + ebx]; пересылки значения массива в младший регистр al
inc ebx
mov bl, byte ptr [esi + ebx]; пересылки значения массива в младший регистр bl
mov work1, al
mov work2, bl
and eax, 21h
and ebx, 21h
sub eax, ebx проверка сходимости битов
jz M3
mov iden, 0;идентификатор. Он необходим для суммы.

M2:
mov ebx, prom
inc ebx
loop M1
jmp M4

M3:
mov al, work1
dec iden
jz Q1; если идентификатов = 0, тогда перейти на метку Q1
mov iden, 1
mov bl, work2
Q1: add sum, ax; подсчета суммы
add sum, bx; подсчета суммы
jmp M2

M4:
mov ebx, 0
mov bx, sum; пересылка значение суммы в регистр
invoke wsprintf, \
ADDR st2, \
ADDR ifmt, \
ebx
invoke MessageBox, \; функция вывода значения
NULL, \
addr st2, \
addr st1 \
MB_OK
invoke ExitProcess, 0
end _start; окончания программы

Ввести 2 дробных числа и сложить их и вывести на консоль и в MessageBox.

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

. Model flat, stdcall; задачи линейной модели памяти
; И соглашения ОС Windows
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

ExitProcess proto: DWORD

. Data; директива определения данных
st1 db «Вывод суммы массива! А», 0
st2 db 10 dup (?), 0
ifmt db «Сумма =% d», 0
masivA db 75,31,88,32
sum dw 0
iden db 0
work1 db 0
work2 db 0
prom dd 0

. Code; директива начала кода
_start:
mov eax, 0
mov ebx, 0
mov ecx, 3
mov edx, 0
lea esi, masivA

M1:
mov prom, ebx
mov al, byte ptr [esi + ebx]; пересылки значения массива в младший регистр al
inc ebx
mov bl, byte ptr [esi + ebx]; пересылки значения массива в младший регистр bl
mov work1, al
mov work2, bl
and eax, 21h
and ebx, 21h
sub eax, ebx проверка сходимости битов
jz M3
mov iden, 0;идентификатор. Он необходим для суммы.

M2:
mov ebx, prom
inc ebx
loop M1
jmp M4

M3:
mov al, work1
dec iden
jz Q1; если идентификатов = 0, тогда перейти на метку Q1
mov iden, 1
mov bl, work2
Q1: add sum, ax; подсчета суммы
add sum, bx; подсчета суммы
jmp M2

M4:
mov ebx, 0
mov bx, sum; пересылка значение суммы в регистр
invoke wsprintf, \
ADDR st2, \
ADDR ifmt, \
ebx
invoke MessageBox, \; функция вывода значения
NULL, \
addr st2, \
addr st1 \
MB_OK
invoke ExitProcess, 0
end _start; окончания программы

Программа расчета формулы в языке Ассемблер. Формула имеет вид: D = 4*Pi*Ha*Fi*D0/L

D = 4 * Pi * Ha * Fi * D0 / L

.386; Директива определения типа микропроцессора
. Model flat, stdcall; задачи линейной модели памяти
; И соглашения ОС Windows

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
BSIZE equ 30
. Data; директива определения данных
D0 dword 200;сохранение в 32-разрядной ячейке памяти переменной х
L dword 1; резервирования 32-х разрядов памяти для переменной y
Ha dd 3,4,5
Fi dd 1,2,3
const dd 4

st1 db «Результат вычисления:», 0
st2 db 10 dup (?), 0

. Code; директива начала кода
_start:
lea esi, Ha
lea edi, Fi
mov ebx, 3

m1:
mov ecx, 3
lea edi, Fi
m2:
finit
fldpi; заносим значения Пи
fimul const; Pi * 4
fild dword ptr [esi] fmul; умножаем результат на На
fild dword ptr [edi]; заносим результат Фи
fmul; умножаем результат на Фи
fild D0; заносим значение D0
fmul; умножаем результат на D0
fild L; заносим значение лянда
fdiv; делим результат на лянда
pushad; сохраняем все регистры общего назначения в стек

invoke FpuFLtoA, 0, 10, ADDR st2, SRC1_FPU or SRC2_DIMM
invoke MessageBox, NULL, addr st2, addr st1, MB_OK

popad; считываем из стека

add edi, 4;следующий элемент в массиве
loop m2
add esi, 4; следующий элемент в массиве
dec ebx
jnz m1; переходить на метку m1 пока ebx не станет равна 0

invoke ExitProcess, NULL; возврат управления Windows
; И освобождения ресурсов

end _start;директива окончания программы с именем start