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

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

О

state

db

statejnachine:

 

crap

state,0

jne

notJD

; Состояние 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) в ассемблере есть средства для более эф­фективной реализации данной структуры - все тот же косвенный переход:

state dw offset state_0

state_machine:

state

statej: add       ax, bx ■  Состояние 0: сложение.

mov       state, offset statej 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

state_3

 

 

 

ret

 

 

 

 

state_3:

push

dx

; Состояние

З:

деление.

 

xor

dx, dx

 

 

 

 

div

bx

 

 

 

 

pop

dx

 

 

 

 

mov

state,offset

state_0

 

 

 

ret

 

 

 

 

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