Табличная функция - Assembler

Узнай цену своей работы

Формулировка задачи:

Доброго времени суток! Столкнулся с проблемой: Нужно было составить программу для расчета φ(B)=tg(B) на языке Assembler, где B=[28..34] с заданной погрешностью: δ= 5%. δ= (φ(B)-φприближ(B))/(φ(B)max-φ(B)min) , где φ(B)приближ - приближенное знач. фун в заданном аргументе φ(B)max,min - максимальное и минимальное значения фун в области определения B/ Я нашел точные значения tg на всем интервале: x,град ˚ tan(x) 28 0,531709 φmin(B) 29 0,554309 30 0,57735 31 0,600861 32 0,624869 33 0,649408 34 0,674509 φmax(B) С учетом вышеизложенного , зная что Δ = (φ(B)-φприближ(B)), нахожу коридор допустимых значений. Δ ≈ 0,01 Тогда x,град ˚ tan(x) Δ- Δ+ 28 0,531709 0,521709 0,541709 29 0,554309 0,544309 0,564309 30 0,57735 0,56735 0,58735 31 0,600861 0,590861 0,610861 32 0,624869 0,614869 0,634869 33 0,649408 0,639408 0,659408 34 0,674509 0,664509 0,684509 Строю график: Определил необходимый шаг, для того, чтобы погрешность не выходила за 5%: δ(шаг)≈0,31. С учетом этого шага, создал таблицы аргументов и соответствующих функций: ARGUM DW 28000, 28312, 28622, 28930 DW 29236, 29541, 29843 DW 30144, 30443, 30740 DW 31036, 31329, 31621, 31911 DW 32199, 32485, 32770 DW 33052, 33333, 33612, 33890 DW 34165 {задаем таблицу значений tg(B)} FUN DW 532, 539, 546, 553 DW 560, 567, 574 DW 581, 588, 595 DW 602, 609, 616, 623 DW 630, 637, 644 DW 651, 658, 665, 672 DW 679 Далее, начал реализовывать программу. Фрагмент: modul 1.
TITLE laba10_1
PAGE   ,132
PUBLIC TAN, SQRTA ; объявляем процедуры доступные для др. модулей
STK     SEGMENT PARA    STACK   'STACK'
         DB      5       DUP('STACK   ')
STK     ENDS
 
DSEG    SEGMENT PARA    PUBLIC  'DATA'
 
{задаем таблицу аргументов B}
ARGUM   DW 28000, 28312, 28622, 28930
    DW 29236, 29541, 29843
    DW 30144, 30443, 30740
    DW 31036, 31329, 31621, 31911
    DW 32199, 32485, 32770
    DW 33052, 33333, 33612, 33890
    DW 34165
 
{задаем таблицу значений  tg(B)}
FUN DW 532, 539, 546, 553
    DW 560, 567, 574
    DW 581, 588, 595
    DW 602, 609, 616, 623
    DW 630, 637, 644
    DW 651, 658, 665, 672
    DW 679
 
DSEG ENDS
 
SUBTTL
              PAGE
CSEG    SEGMENT PARA    PUBLIC  'CODE'
ASSUME  CS:CSEG,SS:STK,DS:DSEG
 
{ПРОЦЕДУРА ДЛЯ ОПРЕДЕЛЕНИЯ ФУНКЦИИ(ВНАЧАЛЕ AX- АРГУМЕНТ, В КОНЦЕ AX – ЗНАЧЕНИЕ tg(B)}
TAN proc FAR
    PUSH DX  {ПОМЕСТИТЬ В СТЕК РЕГИСТР DX}
    PUSH CX {ПОМЕСТИТЬ В СТЕК РЕГИСТР CX}
    PUSH BX {ПОМЕСТИТЬ В СТЕК РЕГИСТР BX}
    MOV DI, 0 { ОБНУЛЯЕМ СЧЕТКЧИК DI}
 
OPR_A:  ADD DI, 2 ; { ЗАПИСЫВАЕМ В СЧЕТЧИК ЗНАЧЕНИЕ 2-  Di<-DI+2}
    MOV CX, ARGUM[DI] ;  {ЗАПИСЫВАЕМ  В CX  прав.часть интервала ARGUM[DI]}
    CMP CX, AX ; {СРАВНИВАЕМ Выбранное число с табл: если CX<AX , то}
    JS OPR_A ; {ПЕРЕЙТИ К OPR_A}
    SUB CX,AX ;{ ИНАЧЕ В CX  ИДЕТ РАЗНОСТЬ ТАБЛ. И ВЫБР.ЧИСЛА CX – AX}
    MOV DX, AX ; {ЗАПИСЫВАЕМ В DX ЗНАЧЕНИЕ ВЫБРАННОГО АРГУМЕНТА}
    SUB DX, ARGUM[DI-2] {Записываем в DX лев. часть интервала DX -ARGUM[DI-2]}
    CMP CX, DX ;  {если CX<DX, то}
    JS NEXT ; { перейти к NEXT,}
    SUB DI, 2 ; {иначе уменьшаем интервал  DI <- DI – 2}
NEXT:   MOV AX, FUN[DI] ; { ЗАПИСЫВАЕМ В АХ ПОДХОД ЗНАЧ. ТАНГЕНСА}
    POP BX {ИЗВЛЕКАЕМ ИЗ СТЕКА РЕГИСТР BX}
    POP CX {ИЗВЛЕКАЕМ ИЗ СТЕКА РЕГИСТР CX}
    POP DX{ИЗВЛЕКАЕМ ИЗ СТЕКА РЕГИСТР DX}
    RET
...
Все бы ничего, но мне сказали, что нерационально сделано( для микроконтроллеров занимает память) Т.е. не нужно было задавать таблицу аргументов(ARGUM), а нужно по заданному аргументу( к примеру,30) и шагу, сопоставить значения этого аргумента в таблице значений арфгумента (FUN). Т.е. каждое значение (FUN) имеет свой номер, которое соответствует своему аргументу.

Вопрос:

Как мне изменить строки 42-51, не меняя при этом весь код модуля, чтобы обойтись без таблицы аргументов, и подобрать для необходимого аргумента из интервала 28..34 (к примеру 30) значение функции? Спасибо. с ув.Андрей.

Решение задачи: «Табличная функция»

textual
Листинг программы
SUB ,AX,28000
MOV BX,310    ;BX = h = 310 
XOR DX,DX
DIV  BX ;AX = индекс
MOV DI,AX
SHL DI,2
MOV AX,FUN[DI] ;значение из таблицы

Объяснение кода листинга программы

  1. Сначала вычитается 28000 из AX (SUB AX,28000).
  2. Затем в BX записывается 310 (MOV BX,310).
  3. Далее, DX очищается с помощью XOR DX,DX.
  4. Производится деление на BX (DIV BX).
  5. Результат деления сохраняется в DI (MOV DI,AX).
  6. Значение в DI сдвигается вправо на 2 позиции (SHL DI,2).
  7. Из таблицы FUN[DI] берется значение, которое записывается в AX (MOV AX,FUN[DI]). Значение переменной AX после выполнения всех операций будет содержать значение из таблицы FUN[310].

Оцени полезность:

14   голосов , оценка 3.786 из 5