Вычисления значения функции в формате с плавающей запятой - Assembler
Формулировка задачи:
Задание такое - Написать программу для решения функции y=х^2-x^4, где х меняется от -2 до +2 с шагом 0,5. Нужно вычислить функцию на каждом шаге. В формате вычисления с плавающей комой.
Процессор х86.
Такие вопросы
Как после выполнения всех подпрограмм занести результат со смещением 4 байта и в какой регистр его лучше занести ?
Будет ли уменьшатся сх после того как мы его достанем из стека и выполним цикл. То есть сначала в сх 8, после того выполнили цикл, он должен стать 7, но поскольку мы достаём из стека сх со значением 8, значит сх не уменьшается. Во общем если сх не уменьшается, то как сделать так что бы программа выполнилась 8 раз и закончилась ?
TITLE Курсова робота EXTERN MULFXX, MULFXY, ADDSUBFYZ, ADDSUBFYZ STACK SEGMENT PARA STACK “STACK” DB 64 DUP (0) STACK ENDS DSEG SEGMENT PARA PUBLIC “DATA” X DD -2.0 DX DD 0.5 Y DD 1 DUP (0) Z DD 1 DUP (0) R DQ 8 DUP (0) DSEG ENDS CSEG SEGMENT PARA PUBLIC “CODE” ASSUME CS:CSEG, DS:DSEG, SS:STACK MAIN PROC FAR mov ax,DSEG mov ds,ax mov cx,8 ; по скольку нужно сделать исчисления от -2 до +2 с шагом 0,5 заносим в счётчик(сх) 8 push cx ; заносим в стек сх, по скольку в подпрограммах используется регистр сх Start: call MULFXX ; Возводим Х в квадрат и заносим результат в Y call MULFYY ; Возводим Х в 4 степень и заносим результат в Z call ADDSUBFYZ ; Y-Z pop cx ; достаём сх из стека для цикла call ADDSUBFXDX ; для реализации шага выполняем эту подпрограмму, то есть x-dx, то есть 2.0-0,5, то есть, если сначала в Х было значение -2.0, то теперь там -1.5 loop Start ; цикл
Решение задачи: «Вычисления значения функции в формате с плавающей запятой»
textual
Листинг программы
Start: lea si,Y lea di,Z mov bx,[si+2] mov si,[si] mov dx,[di+2] mov di,[di] ; Переход к подпрограммам сложения, вычитания call ADDSUBF ADDSUBF PROC ; Сравнить знаки операндов и определить операцию @addf: mov al,bh ; Сравнить xor al,dh ; знаки операндов jns @addf1 ; Знаки операндов одинаковы xor dh,80h ; Знаки различны, jmp @subf ; перейти к вычитанию ; ; Проверить операнды на нуль @addf1: mov ax,dx ; Проверить на нуль or ax,di ; второй операнд jz @addf8 ; Результат в BX:SI mov ax,bx ; Проверить на нуль or ax,si ; первый операнд jnz @addf2 ; Оба операнда не нулевые xchg bx,dx ; Первый операнд равен нулю, xchg si,di ; сумма равна jmp @addf8 ; второму операнду ; ; Оба операнда не нулевые можно складывать. @addf2: mov ah,bh ; Сравнить общий знак в АН shl bx,1 ; Восстановить скрытый бит stc ; мантиссы первого операнда rcr bl,1 shl dx,1 ; Восстановить скрытый бит stc ; мантиссы второго операнда rcr dl,1 ; Сранить порядки, образовать разность порядков cmp bh,dh ; Сравнить порядки jnc @addf3 ; Порядок числа в BX:SI больше xchg bx,dx ; Передать большее число xchg si,di ; в BX:SI @addf3: sub bh,dh ; Образовать разность порядков jz @addf6 ; Порядки одинаковы cmp bh,24 ; Сравнить разность порядков с 24 jc @addf5 ; Разность порядков меньше 24 jmp @addf7 ; Результата в BX:SI ; Необходимо сдвигать вправо мантиссу меньшего числа в DL:DI @addf5: shr dl,1 ; Сдвинуть мантиссу rcr di,1 inc dh ; Увеличить меньший порядок dec bh ; Декремент разности порядков jnz @addf5 ; Повторять сдвиг mov bh,dh ; Передать порядок в BH ; ; Можно складывать мантиссы. В регистре DH общий порядок @addf6: add si,di ; Сложить младшие части мантисс adc bl,dl ; Сложить старшие части мантисс jnc @addf7 ; Нарушения нормализации влево нет inc dh ; Скорректировать порядок cmp dh,255 ; Проверить переполнение stc jz @addf8 ; Возникло пререполнение rcr bl,1 ; Сдвинуть rcr si,1 ; мантиссу вправо mov bh,dh ; Передать порядок в BH ; ; Форматировать результат @addf7: add ah,ah ; Знак во флаге переноса rcr bh,1 ; Знак числа на месте rcr ah,1 ; Младший бит порядка в АН7 or ah,7fh ; Образовать мантиссу and bl,ah ; Образовать второй байт числа @addf8: ret ; ; Сохранить результат lea di,Z mov [di],si mov [di+2],bx jmp Start ;ret @subf: ; Проверить операнды на нуль @subf1: mov ax,dx ; Проверить на нуль or ax,di ; второй операнд jz @subfa ; Результат в BX:SI mov ax,bx ; Проверить на нуль or ax,si ; первый операнд jnz @subf2 ; Оба операнда не нулевые xchg bx,dx ; Первый операнд равен нулю, xchg si,di ; разность равна xor bh,80h ; второму операнду jmp @subfa ; с измененным знаком ; ; Оба операнда не нулевые можно вычитать. @subf2: mov ah,bh ; Сохранить знак уменьшаемого shl bx,1 ; Восстановить скрытый бит stc ; мантиссы уменьшаемого rcr bl,1 shl dx,1 ; Восстановить скрытый бит stc ; мантиссы вычитаемого rcr dl,1 ; Проверить отношения между числами cmp bh,dh ; Сравнить порядки jnz @subf3 ; Порядки не равны cmp bl,dl ; Сранить старшие байты мантисс jnz @subf3 ; Они не равны cmp si,di ; Сравнить младшие слова мантисс jnz @subf3 ; Они не равны mov bx,0 ; Числа равны, mov si,0 ; разность равна нулю jmp @subfa ; Операнды не равны, необходимо вычитать. @subf3: jnc @subf4 ; Уменьшаемое больше вычитаемого xchg bx,dx ; Вычитаемое больше уменьшаемого, xchg si,di ; обменять числа xor ah,80h ; Изменить знак результата ; Образовать разность порядков. @subf4: sub bh,dh ; Разность порядков в BH jz @subf7 ; Порядки одинаковы cmp bh,24 ; Сравнить разность порядков с 24 jc @subf6 ; Разность порядков меньше 24 jmp @subf9 ; Результата в BX:SI ; Необходимо сдвигать вправо мантиссу менишего числа в DL:DI @subf6: shr dl,1 ; Сдвинуть мантиссу rcr di,1 inc dh ; Увеличить меньший порядок dec bh ; Декремент разности порядков jnz @subf6 ; Повторять сдвиг mov bh,dh ; Передать общий порядок в BH ; Вычитание мантисс и образование результата. @subf7: sub si,di ; Вычесть мантиссы sbb bl,dl @subf8: or bl,bl ; Проверить старший бит мантиссы js @subf9 ; Результат нормализован dec bh ; Декремент порядка cmp bh,255 ; Проверить переполнение stc ; Установить флаг переноса jz @subfa ; Возникло антипереполнение shl si,1 ; Сдвинуть мантиссу влево rcl bl,1 jmp @subf8 ; Повторять до нормализации ; Форматировать результат @subf9: add ah,ah ; Знак во флаге переноса rcr bh,1 ; Знак числа на месте rcr ah,1 ; Младший бит порядка в АН7 or ah,7fh ; Образовать мантиссу and bl,ah ; Образовать второй байт числа @subfa: ret ; ; Сохранить результат mov ax,si ; младшая часть ответа в ах lodsw ; младшая часть ответа из ах по адресу di, а di+2 mov ax,bx ; старшая часть ответа в ах lodsw ; старшая часть ответа из ах по адресу di, а di+2 ADDSUBF ENDP
Объяснение кода листинга программы
- Сначала код вычисляет значение функции в формате с плавающей запятой.
- В начале кода происходит загрузка значений функций в регистры SI и ZD.
- Затем происходит сравнение знаков операндов и определение операции.
- Если знаки операндов одинаковы, то выполняется сложение.
- Если знаки операндов различны, то выполняется вычитание.
- Далее происходит проверка операндов на нуль.
- Если один из операндов равен нулю, то результат функции равен второму операнду.
- Если оба операнда не равны нулю, то происходит проверка отношений между числами.
- Если числа равны, то результат функции равен нулю.
- Если числа не равны, то выполняется вычитание.
- Затем происходит образование разности порядков.
- Далее происходит сдвиг мантиссы меньшего числа вправо.
- Затем происходит вычитание мантисс и образование результата.
- После этого происходит форматирование результата.
- В конце кода результат функции сохраняется в памяти.
ИИ поможет Вам:
- решить любую задачу по программированию
- объяснить код
- расставить комментарии в коде
- и т.д