Приветствую Вас на наших уроках по ассемблеру. Сегодня мы поговорим о арифметических операциях. Сразу хочу сказать о том что все наши дальнейшие уроки будут проходить с использованием FASM ассемблера, а не TASM как это было в первом и во втором. Особо сложного вы ничего не увидите при переходе на fasm. Связано это с тем что fasm поддерживается разработчика по сегодняшний день, что нельзя сказать про tasm. Также в сегодняшнем уроке нам понадобиться отладчик про который шла речь на прошлом уроке.
Сложение и вычитание
Начнем пожалуй с самого простого это сложение и вычитание. В ассемблере за них отвечают две команды это ADD и SUB. Они могут работать как переменными так и с регистрами процессора, а точнее можно сложить или вычесть регистр с регистром, регистр с памятью и наоборот. Пример программы на fasm:
01
org100h
02
movax,1
03
movbx,4
04
addax,bx
05
addbx,[B]
06
movcl,3
07
addcl,[A]
08
add[B],ax
09
movax,4c00h
10
int21h
11
A db2
12
B dw3
В данном примере мы сначала в mov ax,1 заносим в ах регистр единицу затем в bx 4 и прибавляем к ax bx и результат сохраняется в ax. Так же я думаю Вы заметили что в нашей программе есть две переменные, переменная А размером в байт и переменная B размером в слово(два байта). Затем мы к bx прибавляем слово, то есть переменную B и результат соответственно будет в регистре bx. далее мы младшей части регистра cl присваиваем значение 3 и прибавляем в следующей командой сложения переменную А, которая имеет размер один байт. И команда add [B],ax прибавляет к переменной B значение регистра ax, и результат будет в переменной B что мы и видим на рисунках выше.
Команда вычитания по действию нечем не отличаться от команды сложения. Вот пример кода, который Вы можете самостоятельно протрассировать на отладчике:
01
org100h
02
movax,1
03
movbx,7
04
subbx,ax
05
subbx,[B]
06
movcl,3
07
subcl,[A]
08
sub[B],ax
09
sub[B],2
10
movax,4c00h
11
int21h
12
A db2
13
B dw4
Посмотрите на строчку кода sub [B],2 — тут происходит вычитание 2 с переменной B. Такие же действия можно проводить и со сложением. Данная команда также применима и к регистрам к примеру если Вам нужно прибавить к регистру ах 3 то это можно сделать таким образом: add ax,3
В языке ассемблер и соответственно в процессорах х86 существует команда которая автоматически увеличивает либо уменьшает регистр или переменную на единицу.
INC — увеличивает(прибавляет единицу). DEC — уменьшает(вычитает единицу)
view sourceprint?
1
incax
2
decbx
3
inccl
4
decch
5
inc[A]
6
dec[B]
Как известно один байт имеет восемь бит, соответственно может вместит в себя 28= 256 символов. Если мы работаем с положительными (без знаковыми) данными то в байт может поместиться от 0 до 255. Ну а если мы работаем с данными которые могут быть как положительные так и отрицательные то один байт содержит от -128 до +127, а слово в свою очередь от -32768 до +32767. И во многих случаях это нужно учитывать. А теперь представим что нам нужно прибавить регистру bx отрицательное значение которое содержится в младшей части регистра ax. Соответственно прибавит так не получиться, так как bx имеет размер в слово а al в байт. И если просто прибавить к bx значение то что в al путем обнуления старшей части регистра ax и сложением этих двух регистров приведет к тому что отрицательное число с al будет принято за положительное (это было бы приемлемо для без знакового сложения но не для знакового). К примеру если в al=-5 то в регистре содержится число 251 и соответственно оно будет прибавлено к bx а не -5. Для решения этой проблемы существует команда CBW которая расширяет al до ax, к примеру:
view source
1
moval,-5
2
movbx,8
3
cbw
4
addbx,ax
После выполнения этих действий можно увидеть что регистр bx будет равен трем.
Пожалуй и все по поводу сложения и вычитания в ассемблере. До встречи на следующей статье ассемблер уроки. Желаю Вам успехов.