Сложение чисел в ассемблере

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

Также напомню, что мы работаем в MASM32, и соответственно, вам необходимо его установить. Как это сделать, мы рассказывали в прошлой статье по Assembler.

Как создавать файлы Assembler

Прежде чем привести вам код программы, думаю, не лишним будет написать как и где прописывать код:

1. Создать любой файл с расширением .txt

Не так важно с помощью какой программы вы это сделаете(блокнот, Notepad, и тд)

2. Пишем сам код в этом файле(пример кода будет ниже)

3. Переименовываем этот файл в файл с расширением .asm

4. Перемещаем файл в папку BIN(папка, которую использовали в 1 статье)

Код сложения чисел на Assembler

Ну и собственно небольшой код программы:

Ну что ж, вот так вот выглядит код на Assembler.
Первые 2 строчки являются обязательными для MASM, поэтому их мы будем писать в каждой программе. Они обозначают тип процессора и модель памяти с которой мы работаем.

Третья строчка — это раздел переменные( после этой строки, должны объявляться переменные), как вы видите, у нас в этой программе не будет переменных.

Четвертая — раздел кода. В нашей программе, мы помещаем в регистр eax значение 3, а затем с помощью add(прибавить) добавляем 2, логично, что теперь в этом регистре будет храниться значение 5.
Кто не знает, что такое регистр, то вам лучше почитать об этом здесь.
Затем идет команда ret, которая говорит о выходе из программы и сам выход end start.

Как запускать программы

Итак, мы имеем файл с расширением .asm, лежащий в папке BIN.
Поздравляю вас, это первый код на Assembler!
Но все же, пока не очень понятно, как нам проверить: работает ли программа(то есть скомпилировалась ли она и может ли запускаться)?
Для этого мы ее сейчас и запустим:

1. Запускаем командную строку(прописать cmd в поиске, ну или другим способом)

2. Перейти в папку BIN с помощью команды cd

У меня эта команда будет выглядеть так: cd C:UsersНикитаBIN

3. Пишем следующую запись: amake.bat имя файла(без расширения)

Я прописываю: amake.bat first

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

Жмем enter
Если ошибок не возникло то у вас появится что то вроде этого:

Читайте также:  Сериалы на подобии выжить после

Запуск отладчика OLLYDBG

Программа скомпилировалась, а это уже хорошо, теперь нам нужно проверить как она сработала, вдруг она не сложила 2 числа.
Для этого в папке BIN открываем наш отладчик(который устанавливали в 1 статье) OLLYDBG.
В отладчике открываем файл программы (file > open first.exe), и видим наш код уже с другой стороны:

Так как мы работаем с регистром eax, то именно его значение и будем отслеживать.(в правом окне, 1 значение регистров)
Итак, чтобы пошагово прогнать нашу программу нужно нажать на 4 синию кнопку слева.(стрелка вниз с 3 точками)
После 1 нажатия, значение в eax стало равно 3, после 2 нажатия — 5.
Наша программа работает верно!

Итак, казалось бы простая программа сложения 2 чисел на Assembler, а сколько всего узнали! На сегодня все, оставляйте свои комментарии, если у вас есть вопросы или пожелания.

Учебный курс. Часть 9. Сложение и вычитание

Автор: xrnd | Рубрика: Учебный курс | 28-03-2010 | Распечатать запись

Теперь мы уже знаем, как представляются числа в компьютере, и можем перейти к изучению команд процессора. Начнём с самых простых арифметических операций: сложения и вычитания.

Сложение

Для сложения двух чисел предназначена команда ADD. Она работает как с числами со знаком, так и с числами без знака (это особенность дополнительного кода).

Операнды должны иметь одинаковый размер (нельзя складывать 16- и 8-битное значение). Результат помещается на место первого операнда. В общем, эти правила справедливы для большинства команд.

После выполнения команды изменяются флаги, по которым можно определить характеристики результата:

  • Флаг CF устанавливается, если при сложении произошёл перенос из старшего разряда. Для беззнаковых чисел это будет означать, что произошло переполнение и результат получился некорректным.
  • Флаг OF обозначает переполнение для чисел со знаком.
  • Флаг SF равен знаковому биту результата (естественно, для чисел со знаком, а для беззнаковых он равен старшему биту и особо смысла не имеет).
  • Флаг ZF устанавливается, если результат равен 0.
  • Флаг PF — признак чётности, равен 1, если результат содержит нечётное число единиц.

add ax,5 ;AX = AX + 5 add dx,cx ;DX = DX + CX add dx,cl ;Ошибка: разный размер операндов.

Вычитание

Вычитание выполняется с помощью команды SUB. Результат также помещается на место первого операнда и опять же выставляются флаги. Единственная разница в том, что происходит вычитание, а не сложение.

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

sub si,dx ;SI = SI – DX neg ax ;AX = -AX

Инкремент и декремент

Очень часто в программах используется операция прибавления или вычитания единицы. Прибавление единицы называется инкрементом, а вычитание — декрементом. Для этих операций существуют специальные команды процессора: INC и DEC. Обратите внимание, что эти команды не изменяют значение флага CF.

Пример программы

Читайте также:  Расписание школьника на неделю шаблон распечатать

Чтобы всё стало совсем понятно, напишем небольшую программу. Требуется вычислить значение формулы: e=a-(b+c-1)+(-d). Все числа являются 8-битными целыми со знаком. Объявим их после кода и придумаем какие-нибудь значения. Вот что у меня получилось:

use16 ;Генерировать 16-битный код org 100h ;Программа начинается с адреса 100h mov al,[a] ;Загружаем значение a в AL mov ah,[b] ;Загружаем значение b в AH add ah,[c] ;AH = AH + c = b+c dec ah ;AH = AH – 1 = b+c-1 sub al,ah ;AL = AL – AH = a-(b+c-1) mov cl,[d] ;CL = d neg cl ;CL = -CL = -d add al,cl ;AL = AL + CL = a-(b+c-1)+(-d) mov [e],al ;Сохраняем результат в e mov ax,4C00h ; int 21h ;/ Завершение программы ;——————————————————- a db 2 b db 3 c db 5 d db -8 e db ?

Квадратные скобки означают, что операнд находится по адресу, указанному внутри этих скобок. Так как вместо имени переменной FASM подставляет её адрес, то такая запись позволяет прочитать или записать значение переменной.

Запустив программу в Turbo Debugger, можно посмотреть её выполнение по шагам. Значения переменных можно увидеть в окне дампа памяти. Для этого нужно кликнуть правой кнопкой в этом окне и выбрать в меню пункт Goto…. Переменные начинаются в памяти с адреса 011Fh (этот адрес в первой команде).

В этих байтах легко угадываются наши переменные:

Упражнение

Напишите программу для вычисления формулы k=m+1-(n-1-r). Все числа 16-битные целые со знаком. Запустите в отладчике и проверьте правильность вычисления. Результаты можете выкладывать в комментариях 🙂

Приветствую Вас на наших уроках по ассемблеру. Сегодня мы поговорим о арифметических операциях. Сразу хочу сказать о том что все наши дальнейшие уроки будут проходить с использованием FASM ассемблера, а не TASM как это было в первом и во втором. Особо сложного вы ничего не увидите при переходе на fasm. Связано это с тем что fasm поддерживается разработчика по сегодняшний день, что нельзя сказать про tasm. Также в сегодняшнем уроке нам понадобиться отладчик про который шла речь на прошлом уроке.

Сложение и вычитание

Начнем пожалуй с самого простого это сложение и вычитание. В ассемблере за них отвечают две команды это ADD и SUB. Они могут работать как переменными так и с регистрами процессора, а точнее можно сложить или вычесть регистр с регистром, регистр с памятью и наоборот. Пример программы на fasm:

В данном примере мы сначала в mov ax,1 заносим в ах регистр единицу затем в bx 4 и прибавляем к ax bx и результат сохраняется в ax. Так же я думаю Вы заметили что в нашей программе есть две переменные, переменная А размером в байт и переменная B размером в слово(два байта). Затем мы к bx прибавляем слово, то есть переменную B и результат соответственно будет в регистре bx. далее мы младшей части регистра cl присваиваем значение 3 и прибавляем в следующей командой сложения переменную А, которая имеет размер один байт. И команда add [B],ax прибавляет к переменной B значение регистра ax, и результат будет в переменной B что мы и видим на рисунках выше.

Читайте также:  Посчитать сторону треугольника по двум сторонам

Команда вычитания по действию нечем не отличаться от команды сложения. Вот пример кода, который Вы можете самостоятельно протрассировать на отладчике:

Посмотрите на строчку кода sub [B],2 – тут происходит вычитание 2 с переменной B. Такие же действия можно проводить и со сложением. Данная команда также применима и к регистрам к примеру если Вам нужно прибавить к регистру ах 3 то это можно сделать таким образом: add ax,3

В языке ассемблер и соответственно в процессорах х86 существует команда которая автоматически увеличивает либо уменьшает регистр или переменную на единицу.

INC – увеличивает(прибавляет единицу). DEC – уменьшает(вычитает единицу)

Как известно один байт имеет восемь бит, соответственно может вместит в себя 2 8 = 256 символов. Если мы работаем с положительными (без знаковыми) данными то в байт может поместиться от до 255. Ну а если мы работаем с данными которые могут быть как положительные так и отрицательные то один байт содержит от -128 до +127, а слово в свою очередь от -32768 до +32767. И во многих случаях это нужно учитывать. А теперь представим что нам нужно прибавить регистру bx отрицательное значение которое содержится в младшей части регистра ax . Соответственно прибавит так не получиться, так как bx имеет размер в слово а al в байт. И если просто прибавить к bx значение то что в al путем обнуления старшей части регистра ax и сложением этих двух регистров приведет к тому что отрицательное число с al будет принято за положительное (это было бы приемлемо для без знакового сложения но не для знакового). К примеру если в al=-5 то в регистре содержится число 251 и соответственно оно будет прибавлено к bx а не -5. Для решения этой проблемы существует команда CBW которая расширяет al до ax, к примеру:

После выполнения этих действий можно увидеть что регистр bx будет равен трем что мы и видим на рисунке ниже.

Пожалуй и все по поводу сложения и вычитания в ассемблере. До встречи на следующей статье ассемблер уроки. Желаю Вам успехов.

Leave a Reply

Ваш адрес email не будет опубликован. Обязательные поля помечены *

You may use these HTML tags and attributes:

<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>