Современные решения

для защиты Windows приложений

и восстановления исходного кода
Автор: xen. Дата публикации: 10.08.2004

Функция синуса в 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 ;для интерполяции




Комментарии

отсутствуют

Добавление комментария


Ваше имя (на форуме):

Ваш пароль (на форуме):

Комментарии могут добавлять только пользователи,
зарегистрированные на форуме данного сайта. Если Вы не
зарегистрированы, то сначала зарегистрируйтесь тут

Комментарий: