Отправляет email-рассылки с помощью сервиса Sendsay
  Все выпуски  

Уроки ассемблеру. Быстро и просто. Урок 6


Всем доброго времени суток!

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

Первая часть достаточно простая. Вот основные операторы данного типа:

add — позволяет складывать целые числа,
sub — позволяет вычитать целые числа,
inc — команда инкремента (увеличение на 1),
dec — команда декремента (уменьшение на 1).

Все эти операция производятся не напрямую с целыми числами, а при занесении их в определённый регистр.
Рассмотрим программу.

.286
CSEG segment
assume cs:CSEG, ds:CSEG, es:CSEG, ss:CSEG
org 100h
begin:
;Всё написанное выше пока опускаем.
mov ax,5 ;Устанавливаем значение регистра ax в 5.

add ax,3 ;Прибавляем число 3, ax=8.
sub ax,6 ;Отнимаем число 6, ax=2.
inc ax ;Прибавляем число 1, ax=3 (также inc ax занимает
;меньше места, чем add ax,1).
dec ax ;Отнимаем число 1, ax=2 (также dec ax занимает
;меньше места, чем sub ax,1).

int 20h ;Выходим в DOS.

;Завершение программы.
CSEG ends
end begin


Сохраняем в файле test.asm в кодировке 866, а далее ml test.asm /AT
Далее открываем в отладчике: afdpro test.com. Используя клавишу F2, смотрим, как меняется значение регистра ax при каждом шаге. Ещё раз напомню, что для перехода к началу надо нажать клавишу F3, для выхода - ввести в командной строке отладчика слово quit.
Запускать эту программу мы не будем, поскольку на экране ничего не увидим.

Теперь узнаем о командах условного перехода для беззнаковых данных.


je (иногда пишут jz) - Переход, если равно/ноль
jne (иногда пишут jnz) - Переход, если не равно/не ноль

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



Команда



Перейти, если



Условие перехода

JA
JAE
JB
JBE
JC
JCXZ
JE
JG
JGE
JL
JLE
JNA
JNAE
JNB
JNBE
JNC
JNE
JNG
JNGE
JNL
JNLE
JNO
JNP
JNS
JNZ
JO
JP
JPE
JPO
JS
JZ
выше
выше или равно
ниже
ниже или равно
перенос
CX = 0
равно
больше
больше или равно
меньше
меньше или равно
не выше
не выше и не равно
не ниже
не ниже и не равно
нет переноса
не равно
не больше
не больше и не равно
не меньше
не меньше и не равно
нет переполнения
нет чётности
знаковый бит равен 0
не ноль
переполнение
есть чётность
сумма битов чётная
сумма битов нечётная
знаковый бит равен 1
ноль
CF = 0 и ZF = 0
CF = 0
CF = 1
CF = 1 или ZF = 1
CF = 1
CF = 0
ZF = 1
ZF = 0 или SF = OF
SF = OF
SF <> OF
ZF = 1 или SF <> OF
CF = 1 или ZF = 1
CF = 1
CF = 0
CF = 0 и ZF = 0
CF = 0
ZF = 0
ZF = 1 или SF <> OF
SF <> OF
SF = OF
ZF = 0 и SF = OF
OF = 0
PF = 0
SF = 0
ZF = 0
OF = 1
PF = 1
PF = 1
PF = 0
SF = 1
ZF = 1

Вспомним программу из предыдущего выпуска:

.286
CSEG segment
assume cs:CSEG, ds:CSEG, es:CSEG, ss:CSEG
org 100h
begin:
;Всё написанное выше пока опускаем.
mov cx,5 ;Устанавливаем значение счётчика в 5.

metka:
mov ah,9 ;Загружаем в регистр ah число 9 (указываем функцию).
mov dx,offset helloworld ;Указываем, что за фразу мы будем выводить.
int 21h ;Выводим фразу.
loop metka ;Переходим на метку metka и уменьшаем cx на 1.

int 20h ;Выходим в DOS.

helloworld db 'Hello, world!$' ;Определяем переменную helloworld, доступную побайтно, с фразой
;"Hello, world!". В одинарных кавычках, после знака "!" ставим
;знак "$".

;Завершение программы.
CSEG ends
end begin

Как мы помним, оператор loop позволяет нам организовать нужное количество циклов, загружая необходимое число в регистр cx. Однако, всё то же самое можно сделать и без применения данного оператора (однако, значение регистра cx продолжаем проверять):

.286
CSEG segment
assume cs:CSEG, ds:CSEG, es:CSEG, ss:CSEG
org 100h
begin:
;Всё написанное выше пока опускаем.
mov cx,5 ;Устанавливаем значение регистра в 5.

metka:
mov ah,9 ;Загружаем в регистр ah число 9 (указываем функцию).
mov dx,offset helloworld ;Указываем, что за фразу мы будем выводить.
int 21h ;Выводим фразу.

dec cx ;Вычитаем единицу из регистра cx.
jne metka ;Если cx не равен 0, переходим на метку.

int 20h ;Выходим в DOS.

helloworld db 'Hello, world!$' ;Определяем переменную helloworld, доступную побайтно, с фразой
;"Hello, world!". В одинарных кавычках, после знака "!" ставим
;знак "$".

;Завершение программы.
CSEG ends
end begin


Можно использовать не оператор jne, а je, тогда немного изменится наш алгоритм:

.286
CSEG segment
assume cs:CSEG, ds:CSEG, es:CSEG, ss:CSEG
org 100h
begin:
;Всё написанное выше пока опускаем.
mov cx,5 ;Устанавливаем значение регистра в 5.

metka:
mov ah,9 ;Загружаем в регистр ah число 9 (указываем функцию).
mov dx,offset helloworld ;Указываем, что за фразу мы будем выводить.
int 21h ;Выводим фразу.

dec cx ;Вычитаем единицу из регистра cx.
je metka2 ;Если cx равен 0, переходим на метку 2.
jmp metka ;Переходим на первую метку.

metka2:
int 20h ;Выходим в DOS.

helloworld db 'Hello, world!$' ;Определяем переменную helloworld, доступную побайтно, с фразой
;"Hello, world!". В одинарных кавычках, после знака "!" ставим
;знак "$".

;Завершение программы.
CSEG ends
end begin

Не забудьте просмотреть представленные примеры в отладчике!

В избранное