Сегодня мы узнаем о сложении и вычитании целых чисел, а также о командах условного перехода.
Первая часть достаточно простая. Вот основные операторы данного типа:
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 Не забудьте
просмотреть представленные примеры в отладчике!