2.2 Циклы с условием
В зависимости от использования команды условного перехода можно организовать циклы с условием типа “счетчик” или с логическим условием.
Пример 2.Граф-схема цикла с условием типа “счетчик” (рис.2)
Рис.2
имеет следующий шаблон на Ассемблере
movcx, 4 ; – нижняя граница цикла
met:cmpcx,10 ; - верхняя граница цикла
jeout ; - переход если равно
……………
pushcx
……………
popcx
inccx; шаг индекса цикла
jmpmet
out: …………….
Примечание: КомандаCMP(CoMPare) выполняет сравнение 2-х операндов (CXи 10) путем установления бит вRGF,причем значения операндов не меняются.
Пример 3.Граф-схема цикла с логическим условием (рис.3)
Рис.3
имеет следующий шаблон на Ассемблере:
movcx, 10 ; – нижняя граница цикла
met:cmpcx,4 ; - верхняя граница цикла
jaeout ; - переход есливыше или равно
……………
pushcx
……………
popcx
subcx,2 ; шаг индекса цикла
jmpmet
out: …………….
Пример 4.Оптимизированным вариантом цикла с логическим условием с верхней нулевой границей является шаблон
movcx, 10 ; – нижняя граница цикла
met:jcxzout ; - выход из цикла еслиCX=0
……………
pushcx
……………
popcx
deccx; шаг индекса цикла
jmpmet
out: …………….
Команда JCXZсравнивает содержимое СХ с 0, и при СХ=0 передает управление по адресуOUT.
2.3 Команды безусловного и условных переходов
Как известно, организация циклов связана, во-первых, с формированием условия входа(выхода) в(из) цикла и, во-вторых, с , вычислением адреса входа(выхода) в(из) цикла.
Исключая команду LOOP, формирование условий выполняется программистом с помощью команд условных переходов. Различают знаковые, беззнаковые и специальные арифметические команды условных переходов
Команды условных переходов для беззнаковых данных
Синтаксис |
Описание переходов |
Флаги |
JЕ/JZ <метка> |
Если равно/нуль |
ZF=1 |
JNЕ/JNZ <метка> |
Если не равно/не нуль |
ZF=0 |
JA <метка> |
Если выше |
ZF=0&CF=0 |
JAE <метка> |
Если выше или равно |
CF=0 |
JB <метка> |
Если ниже |
CF=1 |
JBE <метка> |
Если ниже или равно |
CF=1&ZF=1 |
Команды условных переходов для знаковых данных
Синтаксис |
Описание переходов |
Флаги |
JЕ/JZ <метка> |
Если равно/нудь |
ZF=1 |
JNЕ/JNZ <метка> |
Если не равно/не нуль |
ZF=0 |
JG <метка> |
Если больше |
ZF=0SF=OF |
JGE <метка> |
Если больше или равно |
SF=OF |
JL <метка> |
Если меньше |
SFOF |
JLE <метка> |
Если меньше или равно |
ZF=1SFOF |
Специальные команды условных переходов
Синтаксис |
Описание переходов |
Флаги |
JS <метка> |
Если знак отрицательный |
SF=1 |
JNS <метка> |
Если знак положительный |
SF=0 |
JC <метка> |
Если есть перенос |
CF=1 |
JNC <метка> |
Если нет переноса |
CF=0 |
JO <метка> |
Если есть переполнение |
OF=1 |
JNO <метка> |
Если нет переполнения |
OF=0 |
JP <метка> |
Если паритет четный |
PF=1 |
JNP <метка> |
Если паритет нечетный |
PF=0 |
JCXZ <метка> |
Если СХ=0 |
- |
Команда JMP <метка>передает управление по указанному в метке адресу впределах текущего или другого программного сегмента.
Команда JMP имеет 5 вариантов:
Название перехода |
Атрибут метки |
Границы перехода |
Прямой короткий |
SHORT |
-128127 байт, т.е. размер метки – 8 бит |
Прямой ближний |
NEAR PTR |
Текущий сегмент кода и размер метки 16 бит |
Прямой дальний |
FAR PTR |
Другой сегмент кода и размер метки 32 бита |
Косвенный ближний |
WORD PTR |
Меткой явл. регистр или ячейка памяти в 16 бит |
Косвенный дальний |
DWORD PTR |
Меткой явл. регистр или ячейка памяти в 32 бита |
Пример 5.
Jmpshortaddr;прямой короткийпереход наaddr
Jmpaddr;прямой короткийпереход наaddr, еслиaddr- ссылка вверх программы
Jmpnearaddr;прямой ближний переход
Jmpaddr;прямой ближний переход, еслиaddr- ссылка вниз программы
Jmpfarptraddr;прямой дальний переход наaddr,addrпонимается компиляторомTASMкак 32-битная величина
JmpDS:mem1 ;косвенныйближний переход по значению 16-битной ячейкиmem1
Jmpwordptr[bx];косвенныйближний переход по 16-битному адресу ячейки памяти, который определяется косвенно черезBX
JmpDS:mem2 ;косвенныйдальний переход по значению 32-битной ячейкиmem2
Jmpdwordptr[bx];косвенныйдальний переход по 32-битному адресу ячейки памяти, который определяется косвенно черезBX
Задача. По 2-мерному массиву 44 типаWORDпостроить одномерный массив, каждый элемент которого является суммой элементов соответствующего столбца
Решение. Для обхода элементов 2-мерного массива будем использовать базово-индексную адресацию, где база будет определять адрес столбца, а индекс- номер элемента в столбце. При организации циклов следует различать 2 типа регистров:регистры, описывающие количество повторений,(как правило, это регистр общего назначения СХ) ирегистры адресации элементовмассива (базовые и/или индексные регистры).
Составим граф-схему алгоритма решения (рис.5)
Пусть MAS– исходный 2-мерный массив, аREZ- массив результата. Для накопления суммы по текущему столбцу будем использовать регистрDX. Условимся использовать регистр СХ как счетчик повторений при обходе массива по столбцам и при обходе по элементам в пределах столбца. Для адресации элементов будем использовать регистр ВХ как адрес столбца, аSI– как индекс в текущем столбце. Наконец,DI– как индекс элементаREZ.
Поскольку обход MASосуществляется по столбцам, вычисление адреса следующего элемента столбца выполняется по формуле
SI=SI + m*2
Рис.5
Turbo Assembler Version 3.1 19/03/99 18:29:37 Page 1
mas2.asm
1 0000 .model small
2 0000 .data
3 =0004 m=4 ; кол-во столбцов
4 =0004 n=4 ; кол-во строк
5 =0001 const=1
*Warning* mas2.asm(6) Reserved word used as symbol: CONST
6 0000 0001 0002 0003 0004mas dw 1, 2, 3, 4
7 0008 0005 0006 0007 0008 dw 5, 6, 7, 8
8 0010 0009 000A 000B 000C dw 9,10,11,12
9 0018 000D 000E 000F 0010 dw 13,14,15,16
10 0020 04*(????) rez dw 4 dup(?)
11 0000 .stack 128
12 0028 .code
13 ;assume CS:code, DS:data, SS:stack
14 0000 B8 0000s mov ax,@data
15 0003 8E D8 mov ds,ax
16 ; begin
17 0005 2B FF sub di,di ; di=0
18 0007 2B DB sub bx,bx ; bx=0
19 0009 B9 0004 mov cx,m ; внеш. цикл
20 000C 51 met2: push cx
21 000D B9 0004 mov cx,n внутр. цикл
22 0010 33 F6 xor si,si ; si=0
23 0012 BA 0000 mov dx,0
24 0015 03 90 0000r met1: add dx,mas[bx][si]
25 0019 B8 0004 mov ax,m ;
26 001C D1 E0 shl ax,const si=si+m*2
27 001E 03 F0 add si,ax ;
28 0020 E2 F3 loop met1
29 0022 59 pop cx ; востанов. СХ для внеш. цикла
30 0023 89 95 0020r mov rez[di],dx
31 0027 83 C7 02 add di,2
32 002A 83 C3 02 add bx,2
33 002D E2 DD loop met2
34 ; завершение работы
35 002F B8 4C00 mov ax,4c00h
36 0032 CD 21 int 21h
37 end ; begin
Особенность программирования массивовна Ассемблере состоит в том, чтоN-мерные массивы в памяти отображаются как одномерные, поэтому доступ к ячейкеN-мерного массиваmasN, в общем случае, выполняется поформуле:
masN[addr1][addr2]addr3]…..[addrN]