Учебный курс. Часть 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-битными целыми со знаком. Объявим их после кода и придумаем какие-нибудь значения. Вот что у меня получилось:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
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-битные целые со знаком. Запустите в отладчике и проверьте правильность вычисления. Результаты можете выкладывать в комментариях 🙂

Следующая часть »

Комментарии: