Создание односвязного списка переходов для состояния конечного автомата
Также опишем структуру элемента списка переходов и макрокоманду для создания этого элемента. Особенность в том, что в отличие от списка состояний макрокоманда строит не весь список, а только один его элемент. Другая особенность в том, что указатель на полученный односвязный список является ссылкой на последний выделенный элемент списка и именно к этому элементу осуществляется привязка элемента состояния к своему списку переходов, что на самом деле особого значения не имеет.
item_l1st_cross struc ;элемент списка переходов
simbol db 0 :входной символ, при котором автомат переходит
:в состояние ниже (поля id_state_cross и nextjtem) id_state_crossdb 0 идентификатор состояния в списке состояний,
:в которое производится переход
point_state dd 0 ;адрес элемента состояния, в которое производится переход next_item dd 0 :адрес следующего элемента в списке переходов для этого состояния
create_item_cross macro sim:REQ.state:REQ.descr:REQ.head:REQ. Hand_Head:REQ
local ml,@@cycl.exit_m
:создание элемента списка переходов для определенного состояния
:вход:
;регистр ЕВХ - адрес предыдущего (для поля descr.nextjtern),
.-Для первого должен быть равен нулю
:sim - символ ASCII, при поступлении которого производится переход в состояние state
:descr - имя структуры-элемента списка переходов
:state - номер состояния, в которое производится переход
;(если двузначное, то в скобках <>)
:head - имя переменной для хранения указателя на конец списка состояний
;Hand_Head - дескриптор кучи процесса по умолчанию
: выход:
регистр ЕВХ - адрес созданного элемента списка переходов
:флаг cf=l - ошибка: нет такого состояния
сохраняем регистры
push eax
:запрашиваем и инициализируем блок памяти из кучи: :LPVOID HeapAlloc(HANDLE hHeap. DWORD dwFlags. DWORD dwBytes); push type descr ;размер структуры push 0 -.флаги не задаем
push Hand_Head ;описатель кучи call HeapAlloc
mov [eax].next_item.ebx :адрес предыдущего movebx.eax запоминаем адрес текущего