Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Primery_nebolwih_podprogramm_na_Assembl-.doc
Скачиваний:
2
Добавлен:
14.05.2015
Размер:
161.79 Кб
Скачать

Функция синуса в 32-битной системе с фиксированной точкой

Процедура Rsin$ вычисляет тригонометрическую функцию sin от 32-битного аргумента. 32-битная система с фиксированной точкой определяется следующим образом:

;значение переменной F32bit = 4.750

F32bit dw 49152 ;дробная часть (0.75*65536)

dw 4 ;целая часть

Использование процедуры: Входные данные: смещение аргумента в BX, смещение результата в AX. Аргумент задает угол в градусах. Выходные данные: значение функции sin, записываемое в переменную, смещение которой определяется регистром AX. Значения регистров не сохраняются.

Например, sin(30.5°) вычисляется так:

Angle dd 001E8000h ;старший байт=30, младший байт=32768

Result dd ? ;сюда будет записан результат

....

mov AX,offset Result

mov BX,offset Angle

call Rsin$

В результате такого вызова вы получите результат 0.50752 в то время как правильное значени еравно 0.50754

Rsin$ proc

; значение синуса аргумента (двойное слово по смещению BX) вычисленное как двойное слово по смещению AX.

; Угол (по смещению BX) в градусах в диапазоне -360...360.

push AX ;сохраняем смещение результата

mov AX,[BX+2] ;целая часть угла

mov CX,[BX] ;дробная часть угла

mov DX,1 ;знак результата - +1 или -1

or AX,AX ;какой знак?

jns Rsin_1

not AX ;меняем знак

not CX

add CX,1

adc AX,0

neg DX ;также меняется знак результата

Rsin_1: ;теперь имеем угол в диапазоне 0...360

; уменьшаем диапазон до 0...180

cmp AX,180 ;угол больше 180?

jl Rsin_2

sub AX,180

neg DX ;изменяем знак результата

Rsin_2: ;теперь угол AX:CX в диапазоне 0...179.99998

cmp AX,90 ;угол больше 90?

jl Rsin_3

mov BX,180 ;вычисляем 180-угол

sub SI,SI

sub SI,CX

sbb BX,AX

mov AX,BX

mov CX,SI

Rsin_3: ;угол в AX:CX в диапазоне 0...90

push DX ;сохраняем знак результата в стеке

cmp AX,90 ;угол равен 90?

jne R_sin4

mov AX,1 ;возвращаем 1.0000

sub BX,BX

jmp short Rsin_9

R_sin4:

mov SI,offset Rsin_t ;таблица значений синусов

add SI,AX

add SI,AX

sub AX,AX ;целая часть значения синуса

mov BX,[SI] ;дробная часть

or CX,CX ;дробная чать равна 0?

jz Rsin_9

; интерполяция между значениями [SI] и [SI+2]

mov AX,[SI+2]

sub AX,BX ;AX = sin(a+1)-sin(a)

mul CX ;CX=0... 0.9999, результат DX= AX*CX/65536

add BX,DX ;добавим получившийся результат к значению из таблицы

sub AX,AX ;целая часть результата

Rsin_9:

pop DX ;корректируем знак результата AX:BX

or DX,DX

jns Rsin_loppu

not AX ;изменяем знак результата

not BX

add BX,1

adc AX,0

Rsin_loppu:

pop DI ;смещение результата

mov [DI+2],AX ;записываем целую часть

mov [DI],BX ;дробная часть

ret

Rsin$ endp

;таблица синусов

Rsin_t dw 0,1144,2287, 3430, 4572, 5712, 6850, 7987, 9121,10252

dw 11380,12505,13626,14742,15855,16962,18064,19161,20252,21336

dw 22415,23486,24550,25607,26656,27697,28729,29753,30767,31772

dw 32768,33754,34729,35693,36647,37590,38521,39441,40348,41243

dw 42126,42995,43852,44695,45525,46341,47143,47930,48703,49461

dw 50203,50931,51643,52339,53020,53684,54332,54963,55578,56175

dw 56756,57319,57865,58393,58903,59396,59870,60326,60764,61183

dw 61584,61965,62328,62672,62997,63303,63589,63856,64104,64332

dw 64540,64729,64898,65048,65177,65287,65376,65446,65496,65526

dw 0 ;для интерполяции

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]