Массивы структур – таблицы
Поле текущего состояния представляет собой запись, битовые поля которой означают следующее:
- биты 0 и 1 – состояние элемента: 00 – свободен; 01 – используется; 10 – удален;
- бит 2 – тип константы: 0 – десятичная константа; 1 – шестнадцатеричная константа;
- бит 3-0 – не последний элемент таблицы; 1 – последний элемент таблицы.
:prg02_05.asm – программа на ассемблере демонстрации работы с неупорядоченной таблицей ;Вход: файл maket.txt с идентификаторами, среди которых присутствуют ;десятичные и шестнадцатеричные константы. ;Выход: вывод информации о десятичных константах на экран. state_tab struc last_off dw 0;адрес первого байта за концом таблицы elem_free dw 0;адрес первого свободного элемента (Offffh – все занято) ends constant struc state db 0;поле состояния элемента таблицы db 02dh форматирование вывода на экран key db 10 dup (' '):ключ. он же значение константы db 02dh форматирование вывода на экран line db 2 dup (' '):строка файла, в которой встретилась константа endjine db Odh.Oah.'S ;для удобства вывода на экран ends.data s_tab state_tab <> tab constant 19 dup (<>) constant <8.> последний элемент таблицы – бит 3=1 end_tab=$-tab filename db 'maket.txf.0 handle dw 0 :дескриптор файла buf db 240 dup С ') xlat_tab db Odh dup (OO).Odh ;признак конца строки db 'O'-Oeh dup (0) db ':'-'0'+l dup CO');признак цифры 0..9 db 'H'-':' dup (0). ":признак буквы 'Н' db 'h'-'H' dup (0). 'h';признак буквы 'h' db Offh-'h1 dup (00) curjine db 0 .code :открываем файл mov ah. 3dh movdx,offset filename int 21h jc exit:ошибка (cf=l) mov handle.ax;читаем файл: movah.3fh:функция установки указателя mov bx,handle mov ex,240;читаем максимум 240 байт lea dx.buf int 21h jc exit mov ex.ax фактическая длина файла в сх инициализируем дескриптор таблицы s_tab lea si.tab:адрес таблицы в si mov s_tab.elem_fгее.si;первый элемент таблицы – свободен add si.end_tab mov s_tab.last_off,si:адрес первого байта за концом таблицы lea bx.xlat_tab leadi .buf ;cканируем до первого пробела: push ds popes cycll: mov al. ' ' repne scasb – . сканирование до первого пробела jcxz displ.цепочка отсканирована › таблица заполнена push сх :классифицируем символ после пробела (команда XLAT): mov al.[di] xlat emp al. '0':первый символ после пробела – 0 je ml cmpal.Odh:первый символ после пробела – Odh je m2:все остальное либо идентификаторы, либо неверно записанные числа pop сх jmpcycll ml::первый символ после пробела – 0..9: mov si.di;откуда пересылать fmov al. ' ' push di repne scasb сканирование до первого пробела mov cx.di dec ex subcx.si ;сколько пересылать lea di.tab emp s__tab.elem_free.0ffffh:есть свободные элементы? je displ: свободных элементов нет mov di,s_tab.elem_free:адрес первого свободного элемента push di lea di.[di].key rep movsb;пересыпаем в элемент таблицы deed!;Какого типа это константа? emp byte ptr [di].'h' popdi je m4 and [di].state.Ofbh;десятичная константа jmp $+5 m4: or [di].state.100b;шестнадцатеричная константа mov al,cur_line:текущий номер строки в al aam преобразуем в символьное представление or ah.030h mov [di].line,ah or al.030h mov [di+1].line.al:и в элемент таблицы or [di].state.lb;помечаем элемент как используемый :теперь нужно поместить в поле s_tab.elem_free адрес нового свободного элемента пб: emp di .s_tab. 1 ast_of f ja displ add di.type constant:к следующему элементу test [di].state.lb jnz m5; используется › к следующему элементу mov s_tab.elem_fгее.d i pop di pop ex jmpcycU m2: увеличить номер строки inc cur_line jmp cycl 1 displ::отображение на экране элементов таблицы lea di.tab m6: test [di].state.100b jnz m7:выводим на экран строку mov ah.9 mov dx.di int 21h ml: add di .type constant emp di,s_tab.last_off jb m6