| [Назад] [Далее] | ![]() |
Конечный автомат — процедура, которая помнит свое состояние и при обращении к ней выполняет различные действия для разных состояний. Например, рассмотрим процедуру, которая складывает регистры АХ и ВХ при первом вызове, вычитает при втором, умножает при третьем, делит при четвертом, снова складывает при пятом и т.д. Очевидная реализация, опять же, состоит в последовательности условных переходов:
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 state_3
ret
state_3:
push dx ; состояние З: деление
xor dx,dx
div bx
рор dx
mov state,offset state_0
ret
Как и в случае с CASE, использование косвенного перехода приводит к тому, что не требуется никаких проверок и время выполнения управляющей структуры остается одним и тем же для четырех или четырех тысяч состояний.