Четыре основных арифметически действия.
Операция умножения.
Операция деления.
Программирование арифметических выражений в языке Ассемблер происходит через некоторые команды такие, как: mul, div, sub, add. Эти команды называются командами арифметических операций.
Mul – команда умножения. Она умножает регистр ax на то, что стоит после нее. Результат заносится в ax.
Div – команда деления. Она делит регистр ax на то, что стоит после нее. Результат заносится в ax.
Add – команда сложения. Слаживает два числа. Результат заносится в первый регистр.
Sub – команда вычитания. Вычитает два числа. Результат заносится в первый регистр.
Пример: Написать программу на ассемблере вычисления выражения: а – e/b – de;
где а =5;
b =27;
c = 86;
е =1986;
d =1112;
Результат вычисления выражения сохранить в памяти. Навести значение и порядок размещения данные в памяти.
Текст программы
.686; директива определения типа микропроцессора
.model flat,stdcall; задание линейной модели памяти
; но соглашения ОС Windows
.data; директива определения данные
_a dw 5; запись в 16-разрядный амбарчик памяти с именем _а числа 5
_b dw 27; запись _b = 16h
_c dw 86; запись _c = 56h
_e dw 1986; запись _e = 7C2h
_d dw 1112; запись _d = 458
res dw 0; резервирование памяти для сохранения переменной res
.code; директива начала сегмента команд
start:
mov edx,0; очистка регистров
mov ebx,0; очистка регистров
mov ecx,0; очистка регистров
mov ах,_e; в регистр ах заносим число _e = 7C2h
mul _d; множим _e и _d
SHL edx,16; делаем здвиг на 16
mov dx,ax
push edx; бросаем значение в стек
mov edx,0
mov ах,_e
mov cx,_b
div cx; делим ах с cx
pop ecx; достаем из стеку значения
sub ecx,eax; отнимаем
mov ах,_a
sub eax,ecx
mov res, eax
ret; возвращение управление ОС
end start; окончание программы с именем _start
Операция сдвига, циклического сдвига.
|
Сдвиги — это особые операции процессора, которые позволяют реализовать различные преобразования данных, работать с отдельными битами, а также быстро выполнять умножение и деление чисел на степень 2.
Логический сдвиг вправо
Логический сдвиг всегда выполняется без учёта знакового бита. Для логического сдвига вправо предназначена команда SHR. У этой команды два операнда. Первый операнд представляет собой сдвигаемое значение и на его место записывается результат операции. Второй операнд указывает, на сколько бит нужно осуществить сдвиг. Этим операндом может быть либо непосредственное значение, либо регистр CL.
Все биты операнда сдвигаются вправо (от старших битов к младшим). Выдвинутый бит становится значением флага CF. Старший бит получает нулевое значение. Эта операция повторяется несколько раз, если второй операнд больше единицы. Логический сдвиг вправо можно использовать для деления целых чисел без знака на степень 2, причём сдвиг работает быстрее, чем команда деления DIV. Примеры:
shr ax,1 ;Логический сдвиг AX на 1 бит вправо shr byte[bx],cl ;Лог. сдвиг байта по адресу BX на СL бит вправо shr cl,4 ;CL = CL / 16 (для числа без знака) |
Арифметический сдвиг вправо
Арифметический сдвиг отличается от логического тем, что он не изменяет значение старшего бита, и предназначен для чисел со знаком. Арифметический сдвиг вправо выполняется командой SAR. У этой команды тоже 2 операнда, аналогично команде SHR.
Выдвинутый бит становится значением флага CF. Знаковый бит не изменяется. При сдвиге на 1 бит сбрасывается флаг OF. Эту команду можно использовать для деления целых чисел со знаком на степень 2 (обратите внимание, что «округление» всегда в сторону меньшего числа, поэтому для отрицательных чисел результат будет отличаться от результата деления с помощью команды IDIV). Примеры:
|
sar bx,1 ;Арифметический сдвиг BX на 1 бит вправо sar di,cl ;Арифметический сдвиг DI на CL бит вправо sar [x],3 ;x = x / 8 (x - 8-битное значение со знаком) |
Логический и арифметический сдвиг влево
Логический сдвиг влево выполняется командой SHL, а арифметический — командой SAL. Однако, на самом деле это просто синонимы для одной и той же машинной команды. Сдвиг влево одинаков для чисел со знаком и чисел без знака. У команды 2 операнда, аналогично командам SHR и SAR.
Старший бит становится значением флага CF, а младший получает нулевое значение. С помощью сдвига влево можно быстро умножать числа на степень 2. Но будьте внимательны, чтобы не получить в результате переполнение. Если при сдвиге на 1 бит меняется значение старшего бита, то устанавливается флаг OF. Примеры использования команды:
shl dx,1 ;Сдвиг DX на 1 бит влево sal dx,1 ;То же самое shl ax,cl ;Сдвиг AX на CL бит влево sal [x],2 ;x = x * 4 |
Сдвиги двойной точности
Существуют ещё две команды, осуществляющие более сложные сдвиги. SHRD — сдвиг двойной точности вправо, SHLD — сдвиг двойной точности влево. У этих команд 3 операнда. Первый операнд — сдвигаемое значение и место для записи результата, должен иметь размер 16 бит. Второй операнд — источник вдвигаемых битов, тоже должен иметь размер 16 бит и находится в одном из регистров. Значение второго операнда не меняется. Третий операнд — счётчик сдвигов, может быть непосредственным значением или находиться в регистре CL.
|
Небольшой пример использования команды SHLD:
shld ax,bx,3 ;Сдвинуть ax на 3 бита влево, ;3 старших бита BX становятся младшими битами AX |
Циклический сдвиг.
Циклический сдвиг отличается от линейного тем, что выдвигаемые с одного конца биты вдвигаются с другой стороны, то есть движутся по кольцу. В процессора x86 существует 2 вида циклического сдвига: простой и через флаг переноса (CF). У всех команд, рассматриваемых в этой части учебного курса, по 2 операнда, таких же, как у команд линейного сдвига. Первый операнд — сдвигаемое значение и место для записи результата. Второй операнд — счётчик сдвигов, который может находится в регистре CL или указываться непосредственно.
Простой циклический сдвиг
Циклический сдвиг вправо выполняется командой ROR, а влево — командой ROL.
Значение последнего выдвигаемого бита копируется в флаг CF. Для сдвигов на 1 бит устанавливается флаг OF, если в результате сдвига изменяется знаковый бит операнда. (Честно говоря, не помню, чтобы я этим когда-то пользовался. Но может вам пригодится ) Примеры использования команд: