Как решать уравнения на ассемблере

Как решать уравнения на ассемблере

Доброго здоров’ячка! Сегодня я расcкажу вам как решать квадратные уравнения с помощью сопроцесcора . Но, что это такое? Я не буду вдаваться в хардверные дебри, скажу только, что наряду с обычным процессором существует, так называемый, математический сопроцессор. Его функции ясны: чтобы не забивать основной процессор всякими math кодами (некоторые он может вычислить) есть математическая машина.

Математикам: я здесь покажу как программируется сопроцессор на основе решения квадратных уравнений.

Алгоритм решения:

  1. Мы имеем формулу общего квадратного уравнения (вспоминайте школу, класс этак восьмой :-). Она выглядит так: ax^2+bx+c=0
  2. Требуется найти ее дискриминант: D=b^2-4ac
  3. Если D то корней не существует, иначе п.4
  4. Если D=0 то есть один корень: X=-b/2a , иначе п.5
  5. Если D>0 то существуют два корня: X1=(-b-sqrt(D))/2a, X2=(-b+sqrt(D))/2a

С чего же начать? Ответ прост: с очистки математической машины. Почти все программы оставляют свои коды в сопроцессоре (для краткости будем называть его СП). Делается это одной коммандой: finit

Далее, найдем дискриминант:

Ну вот, D нашли. Теперь нужно его сравнить с нулем. Вот тут то и начинаются проблемы: у СП есть момент сравнивания и все, а мне нужно перейти на определенные «полки» программы. Зато у основного процессора (далее ОП) такая возможность есть, а значит, мне нужно перенести определенные флаги СП в ОП. Делается это так:

Теперь мы можем «попрыгать» по программе, но сначала таблица соответсвий:

УсловиеКоманда «прыжка»
jc j1
; если D то goto j1
jz j2
; если D = 0 то goto j2
; а если D > 0 то [далее]
finit
; опять очистили СП
fld temp2
; Введем в стек СП число temp2 (temp2=2)
fmul a
; Умножили temp2 на a
fld D
; Введем в стек СП дискриминант
fsqrt
; Посчитали корень даскриминанта
fld b
; Введем в стек СП число b
fchs
; Изменили знак у b
fsave temp2[4]
; Сохранили полное (регитры и стек) состояние СП (и стерли оное)
frstor temp2[4]
; Загрузили полное состояние
fsubr
; вычли корень дискриминанта из -b
fdivr
; первый корень
frstor temp2[4]
; Загрузили еще раз полное состояние
fadd
; сложили корень дискриминанта и -b
fdivr
; второй корень
jmp ex
; «прыгнули» на «выход»
; D j1:
mov ah, 09h
mov dx, offset mes1
int 21h
; вывели сообщение, что нет корней (под Win32)
jmp ex
; «прыгнули» на «выход»
; D = 0
; X = -b/(2*a)
j2:
finit
; опять очистили СП
fld temp2
; Введем в стек СП число temp2 (temp2=2)
fmul a
; Умножили temp2 на a
fld b
; Введем в стек СП число b
fdivr
; Разделили b на 2a
fchs
; Сменили знак
; Вот и единственный корень

Вот и все! Ошибок я не нашел (может Вы найдете). Можете вводить целые и дробные параметры — все равно получите правильный результат. Если у вас есть TASM (и за мелкими изменениями MASM ) то можете скачать данную программу.

При написании я частично пользовался книгой Юрова ASSEMBLER 2-е издание , за что ему большое спасибо!

Ну вот и все, что я хотел вам сказать. Бувайте!

Видео:FASM. add, sub, mul, div, neg. Арифметика ассемблер. #3Скачать

FASM. add, sub, mul, div, neg. Арифметика ассемблер. #3

Приложение 1. Полная программа на ASM

; >>>>>>>>>>>>>>>>
; Anton (Liloi) Moskalenko
; e-mail: liloi@mail.ru
; >>>>>>>>>>>>>>>>

; Create time & date: 15:55 14.08.2006

; Compiled with TASM 4.1

.286
.model small
.data

a dd 2.0
b dd 4.0
c dd 2.0
D dd ?

mes1 db ‘No roots! $’

temp dd 4.0
temp2 dd 2.0

.stack 256h
.code

;Main PROC
main proc

push @data
pop ds

; discriminante
; C++:
; D = sqr(b)-4*a*c

Видео:ЯЗЫК АССЕМБЛЕРА С НУЛЯ | #1 НАЧАЛОСкачать

ЯЗЫК АССЕМБЛЕРА С НУЛЯ | #1 НАЧАЛО

fld b
fmul b
fld a
fld temp

fmul
fld c
fmul
fsubp st(1),st(0)
fst D

fld temp2
fmul a
fld D
fsqrt
fld b
fchs

fsave temp2[4]
frstor temp2[4]

fsubr
fdivr ; first root

fadd
fdivr ; second root

int main(int argc, char *argv[])
<
const float a = 3, b = 2, c = -1;
float D = 0, x, x1, x2;

Простая программа на ассемблере x86: Решето Эратосфена

Вступительное слово

По своей профессии я не сталкиваюсь с низкоуровневым программированием: занимаюсь программированием на скриптовых языках. Но поскольку душа требует разнообразия, расширения горизонтов знаний или просто понимания, как работает машина на низком уровне, я занимаюсь программированием на языках, отличающихся от тех, с помощью которых зарабатываю деньги – такое у меня хобби.

И вот, я хотел бы поделиться опытом создания простой программы на языке ассемблера для процессоров семейства x86, с разбора которой можно начать свой путь в покорение низин уровней абстракции.

До ее написания я сформулировал такие требования к будущей программе:

  • Моя программа не должна быть программой под DOS. Слишком много примеров ориентировано на нее в связи с простым API. Моя программа обязательно должна была запускаться на современных ОС.
  • Программа должна использовать кучу – получать в свое распоряжение динамически распределяемую память.
  • Чтобы не быть слишком сложной, программа должна работать с целыми беззнаковыми числами без использования переносов.

Видео:ЯЗЫК АССЕМБЛЕРА за 3 МИНУТЫСкачать

ЯЗЫК АССЕМБЛЕРА за  3 МИНУТЫ

Задачей для своей программы я выбрал поиск простых чисел с помощью Решета Эратосфена. В качестве ассемблера я выбрал nasm.

Код я писал с упором больше на стиль и понятность, чем на скорость его выполнения. К примеру, обнуление регистра я проводил не с помощью xor eax, eax , а с помощью mov eax, 0 в связи с более подходящей семантикой инструкции. Я решил, что поскольку программа преследует исключительно учебные цели, можно распоясаться и заниматься погоней за стилем кода в ассемблере.

Итак, посмотрим, что получилось.

С чего начать?

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

Так же встает вопрос, каким образом на таком низком уровне реализуется обмен данными между внутренним миром программы и внешней средой. Тут на сцену выходит API операционной системы. В DOS, как уже было упомянуто, интерфейс был достаточно простой. К примеру, программа «Hello, world» выглядела так:

В Windows же для этих целей используется Win32 API, соответственно, программа должна использовать методы соответствующих библиотек:

Здесь используется файл win32n.inc, где определены макросы, сокращающие код для работы с Win32 API.

Я решил не использовать напрямую API ОС и выбрал путь использования функций из библиотеки Си. Так же это открыло возможность компиляции программы в Linux (и, скорее всего, в других ОС) – не слишком большое и нужное этой программе достижение, но приятное достижение.

Вызов подпрограмм

Потребность вызывать подпрограммы влечет за собой несколько тем для изучения: организация подпрограмм, передача аргументов, создание стекового кадра, работа с локальными переменными.

Подпрограммы представляют собой метку, по которой располагается код. Заканчивается подпрограмма инструкцией ret . К примеру, вот такая подпрограмма в DOS выводит в консоль строку «Hello, world»:

Для ее вызова нужно было бы использовать инструкцию call :

Видео:Как решить уравнение #россия #сша #америка #уравненияСкачать

Как решить уравнение #россия #сша #америка #уравнения

Для себя я решил передавать аргументы подпрограммам через регистры и указывать в комментариях, в каких регистрах какие аргументы должны быть, но в языках высокого уровня аргументы передаются через стек. К примеру, вот так вызывается функция printf из библиотеки Си:

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

При входе в подпрограмму необходимо создать новый стековый кадр. Делается это следующим образом:

Соответственно, перед выходом нужно восстановить прежнее состояние стека:

Для локальных переменных так же используется стек, на котором после создания нового кадра выделяется нужное количество байт:

Так же архитектура x86 предоставляет специальные инструкции, с помощью которых можно более лаконично реализовать эти действия:

Второй параметр инструкции enter – уровень вложенности подпрограммы. Он нужен для линковки с языками высокого уровня, поддерживающими такую методику организации подпрограмм. В нашем случае это значение можно оставить нулевым.

Непосредственно программа

Проект содержит такие файлы:

  • main.asm – главный файл,
  • functions.asm – подпрограммы,
  • string_constants.asm – определения строковых констант,
  • Makefile – сценарий сборки

Рассмотрим код основного файла:

Видно, что программа поделена по смыслу на 5 блоков, оформленных в виде подпрограмм:

  1. input_max_number — с помощью консоли запрашивает у пользователя максимальное число, до которого производится поиск простых; во избежание ошибок значение ограничено константами MIN_MAX_NUMBER и MAX_MAX_NUMBER
  2. allocate_flags_memory — запросить у ОС выделение памяти для массива пометок чисел (простое/составное) в куче; в случае успеха возвращает указатель на выделенную память через регистр eax
  3. find_primes_with_eratosthenes_sieve — отсеять составные числа с помощью классического решета Эратосфена;
  4. print_primes — вывести в консоль список простых чисел;
  5. free_flags_memory — освободить память, выделенную для флагов

Для функций было условлено такое правило: значение возвращается через регистр eax , регистр edx содержит статус. В случае успеха он содержит значение SUCCESS , то есть, 0 , в случае неудачи — адрес строки с сообщением об ошибке, которое будет выведено пользователю.

Видео:АССЕМБЛЕР В 2023. Первый и последний урок.Скачать

АССЕМБЛЕР В 2023. Первый и последний урок.

🎬 Видео

Как решают уравнения в России и США!?Скачать

Как решают уравнения в России и США!?

Как решать уравнения с дробью? #shortsСкачать

Как решать уравнения с дробью? #shorts

Топ 3 худших программиста на YouTube! #код #айти #программистСкачать

Топ 3 худших программиста на YouTube! #код #айти #программист

Ассемблер ДЛЯ НОВИЧКОВ: асм и дизасмСкачать

Ассемблер ДЛЯ НОВИЧКОВ: асм и дизасм

Сложные уравнения со скобками. Как решать уравнения в несколько действий в 5 классе.Скачать

Сложные уравнения со скобками. Как решать уравнения в несколько действий в 5 классе.

Как решать уравнения с модулем или Математический торт с кремом (часть 1) | МатематикаСкачать

Как решать уравнения с модулем или Математический торт с кремом (часть 1) | Математика

Как решают уравнения в России и СШАСкачать

Как решают уравнения в России и США

СУПЕР ЛАЙФХАК — Как решать Иррациональные УравненияСкачать

СУПЕР ЛАЙФХАК — Как решать Иррациональные Уравнения

Как решать Диофантовы уравнения ★ 9x+13y=-1 ★ Решите уравнение в целых числахСкачать

Как решать Диофантовы уравнения ★ 9x+13y=-1 ★ Решите уравнение в целых числах

КАК СПИСАТЬ СЛОЖНЫЕ УРАВНЕНИЯ ПО МАТЕМАТИКЕ, ЕСЛИ ИХ НЕТ В ИНТЕРНЕТЕ? #shortsСкачать

КАК СПИСАТЬ СЛОЖНЫЕ УРАВНЕНИЯ ПО МАТЕМАТИКЕ, ЕСЛИ ИХ НЕТ В ИНТЕРНЕТЕ? #shorts

Решаем уравнение быстро #shortsСкачать

Решаем уравнение быстро #shorts

Решение простых уравнений. Что значит решить уравнение? Как проверить решение уравнения?Скачать

Решение простых уравнений. Что значит решить уравнение? Как проверить решение уравнения?

Вся суть уравнений за 1 секунду. Хватит путать знаки в уравнениях!Скачать

Вся суть уравнений за 1 секунду. Хватит путать знаки в уравнениях!
Поделиться или сохранить к себе: