Сложные структуры данных. Перечислимые типы данных. Прерывания пользователя, страница 2

8.4. Множества

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

Мы будем рассматривать только конечные упорядоченные множества.

Поэтому, представление множества в памяти машины может моделироваться массивом бит, состояние каждого из которых символизирует присутствие (=1) или отсутствие (=0) данного элемента в текущем множестве. Очевидно, что при таком подходе для множества мощностьюn потребуется n бит или, в общем случае, n/8+1 байт памяти. Будем предполагать, что самый левый бит, в выделенный последовательности байт, отвечает за состояние первого элемента, следующий – за состояние второго и т.д.

Следующая программа показывает пример того, как можно ответить на  вопрос о том, принадлежит ли некоторый элемент предъявленному множеству:

.model       small

.386

.stack         256

beepspkr   macro        times:=<1>

push ax

push dx

mov  ah,2

mov  dl,7

rept   times

int    21h

endm

pop   dx

pop   ax

endm

Inmn macro        name,tp:req,k

;; Результат операции k in name определяется состоянием fc

ifndef name

.err   'Имя &name не определено'

exitm

elseifndef  k

.err   'Имя &k не определено'

exitm

endif

if       k gt tp

clc

exitm

endif

push ax

push bx

mov  ax,k

mov  bh,8

div    bh     ;; ah=номер бита, al=номер байта

mov  bl,al

xor    bh,bh

mov  bl,byte ptr name[bx]

shr    ax,8

BTS  bx,ax

pop   bx

pop   ax

endm

setof macro        name,tp,x

name label byte

kk=0

while kk le tp/8

shablon=0

irp     i,<x>

if i/8 eq kk

shablon = shablon or (1 shl (i mod 8))

endif

endm

db     shablon

kk=kk+1

endm

endm

.data

Alphabet enum   A,B,C,D,E,F,G,H,I,J,K,L,N,M,O,P,Q,R,S,T,V,U,W,X,Y,Z

SETOF VOWELS,Alphabet,<A,E,I,J,O,U>

SETOF CONSONANTS,Alphabet,<B,C,D,F,G,H,K,L,M,N,P,Q,R,S,T,V,W,X,Y,Z>

.code

main proc

mov  ax,@data

mov  ds,ax

inmn VOWELS,Alphabet,B

jnc    short no

beepspkr

no:    .exit  0

main endp

end   main

При этом предполагается, что элементы множества нумеруются начиная с нуля, а биты последнего байта, отведенного компилятором под представление множества, не представляющие ни каких элементов множества обнулены.

Объединение двух подмножеств может быть произведено следующим образом:

AddSets  macro m0,m1,m2,tp

local L

ifndef m0

.err    'Имя &m0 не определено'

exitm

elseifndef  m1

.err    'Имя &m1 не определено'

exitm

elseifndef  m2

.err    'Имя &m2 не определено'

exitm

endif

push ax

push bx

push cx

mov  cx,tp/8

mov  bx,0

L:      mov  al,m1[bx]

or      al,m2[bx]

mov  m0[bx],al

inc    bx

loop  L

pop   cx

pop   bx

pop   ax

endm

8.5. Структуры

В отличие от записей, которые представляют собой набор битовых полей, структуры объединяют в себе переменные различного типа, которые принято называть полями. Структуры ассемблера можно сравнить с записями (record) в Паскале или со структурами (struct) в С/С++.

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

Например, простейший формат структуры, описывающей комплексные числа, может быть представлен следующим образом:

Complex   struc

Re     dd     0.0

Im     dd     0.0

Complex   ends

Сама же переменная комплексного типа может быть описана в сегменте данных:

C      Complex    <1.0,1.0>   ; 1+i

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