Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
SP_MET_2.DOC
Скачиваний:
13
Добавлен:
02.05.2019
Размер:
689.66 Кб
Скачать

2.1.Управляющие структуры

      1. Структуры if... Then... Else

Это часто встречающаяся управляющая структура, передающая управ­ление на один участок программы, если некоторое условие выполняет­ся, и на другой, если оно не выполняется, записывается на ассемблере в следующем общем виде:

(набор команд проверяющих условие)

Jcc Else

(набор команд соответствующих блоку THEN)

Jmp Endif

Else: (набор команд соответствующих блоку ELSE)

Endif:

Для сложных условий часто оказывается, что одной командой услов­ного перехода обойтись нельзя, так что реализация проверки может зна­чительно увеличиться, например, следующую строку на языке С

if (((х>у) && (z<t)) || (a! = b)) c=d;

можно представить на ассемблере как:

;проверка условия

mov ax, A

cmp ax, В

jne then ; если а! = b – условие выполнено

mov ax, X

cmp ax, Y

jng endif ; если х < или = у – условие не выполнено

mov ax, Z

cmp ах, Т

jnl endif ; если z > или = t – условие не выполнено

then: ; условие выполняется

mov ах, 0

mov С, ах

endif:

      1. Структуры case

Управляющая структура типа CASE проверяет значение некоторой пе­ременной (или выражения) и передает управление на различные участ­ки программы. Кажется очевидным, что эта структура должна реализо­вываться в виде серии структур IF... THEN... ELSE.

Пусть переменная i принимает значения от 0 до 2, и в зависимости от значения надо выполнить процедуры case0, case1 и case2:

mov ax, i

cmp ax, 0 ; проверка на 0

jne not0

call case0

jmp endcase not0: cmp ax, 1 ; проверка на 1

jne not1

call case1

jmp endcase not1: cmp ax, 2 ; проверка на 2

jne not2

call case2

not2: endcase:

Но ассемблер предоставляет более удобный способ реализации таких структур — таблицу переходов.

mov bx, i

shl bx, 1 ; умножить ВХ на 2 (размер адреса в таблице

; переходов – 4 для 32-битных адресов)

jmp cs: jump_table[bx] ; разумеется,

; в этом примере достаточно использовать call

jump_table dw foo0, foo1, foo2 ; таблица переходов

foo0: call case0

jmp endcase foo1: call case1

jmp endcase foo2: call case2

jmp endcase

Очевидно, что для большого числа значений переменной способ с таблицей переходов гораздо быстрее (не требуется многочисленных проверок), а если большая часть значений переменной — числа, следую­щие в точности друг за другом (так что в таблице переходов не окажется пустых участков), то эта реализация структуры CASE окажется еще и значительно меньше.

      1. Конечные автоматы

Конечный автомат — процедура, которая помнит свое состояние и при обращении к ней выполняет различные действия для разных состояний. Например, рассмотрим процедуру, которая складывает регистры АХ и ВХ при первом вызове, вычитает при втором, умножает при третьем, делит при четвертом, снова складывает при пятом и т. д. Очевидная ре­ализация, опять же, состоит в последовательности условных переходов:

state db 0

state_machine:

cmp state, 0

jne not_0

; состояние 0: сложение

add ax, bx

inc state

ret

not_0: cmp state, 1

jne not_1

; состояние 1: вычитание

sub ax, bx

inc state

ret

not_1: cmp state, 2

jne not_2

; состояние 2: умножение

push dx

mul bx

pop dx

inc state

ret

; состояние 3: деление

not_2: push dx

xor dx, dx

div bx

pop dx

mov state, 0

ret

Оказывается, что, как и для CASE, в ассемблере есть средства для более эффективной реализации этой структуры. Это все тот же косвен­ный переход, использованный выше для CASE:

state dw offset state_0

state_machine:

jmp state

state_0: add ax,bx ; состояние 0: сложение

mov state, offset state_1

ret

state_1: sub ax, bx ; состояние 1: вычитание

mov state, offset state_2

ret state_2: push dx ; состояние 2: умножение

mul bx

pop dx

mov state, offset stdte_3

ret state_3: push dx ; состояние 3: деление

xor dx, dx

div bx

pop dx

mov state, offset state_0

ret

Как и в случае с CASE, использование косвенного перехода приво­дит к тому, что не требуется никаких проверок и время выполнения уп­равляющей структуры остается одним и тем же для четырех или четы­рех тысяч состояний.

      1. Циклы

Несмотря на то что набор команд Intel включает команды организации циклов, они годятся только для одного типа циклов — FOR-циклов, которые выполняются фиксированное число раз. В общем виде любой цикл записывается в ассемблере как условный переход.

WHILE-цикл: (команды инициализации цикла)

метка: IF (не выполняется условие окончания цикла)

THEN

(команды тела цикла)

jmp-меткa

REPEAT/UNTIL-цикл:

(команды инициализации цикла)

метка: (команды тела цикла)

IF (не выполняется условие окончания цикла)

THEN (переход на метку)

(такие циклы выполняются быстрее на ассемблере и всегда следует стремиться переносить проверку условия окончания цикла в конец)

LOОР/ENDLOОР-цикл:

(команды инициализации цикла)

метка:

(команды тела цикла)

IF (выполняется условие окончания цикла)

THEN jmp метка2

(команды тела цикла)

jmp-метка

метка2:

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]