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

str2   db     'String 2'

str3   db     'String 3'

.stack         256

Heap segment    para

Htop db     Heap_size dup(?)        ; Куча

Heap ends

.code

new  macro        size

ifndef Heap

.err

exitm

elseifndef  Status

.err

exitm

endif

mov  ax,size       ; Размер искомого свободного участка

call    find

endm

delite macro        adr,size

mov  bx,adr                  ; Адрес освобождаемой памяти в bx

mov  cx,size                 ; Размер освобождаемой области

call    clear

endm

Start macro

assume     es:Heap

mov  ax,@data

mov  ds,ax

mov  ax,Heap

mov  es,ax

xor    ax,ax

endm

SaveReg   macro        RegList

irp     reg,<RegList>

push reg

endm

endm

LoadReg   macro        RegList

irp     reg,<RegList>

pop   reg

endm

endm

main proc

Start

new  %type aitem ; Найти подходящую область памяти ;для

; размещения элемента списка

mov  top,ax                  ; Указатель на вершину списка

; Первый элемент

mov  bx,ax                  

mov  cx,8

lea    si,str1

lea    di,[bx].list.fild1

rep    movsb       ;заполнение поля fild1 первого элемента

new  %type aitem                

mov  es:[bx].next,ax    ; адрес второго элемента

mov  es:[bx].list.fild2,'$'

; Второй элемент

mov  bx,ax

mov  cx,8

lea    si,str2

lea    di,[bx].list.fild1

rep    movsb       ;заполнение поля fild1 второго элемента

new  %type aitem

mov  es:[bx].next,ax    ; адрес третьего элемента

mov  es:[bx].list.fild2,'$'

; Третий элемент

mov  bx,ax

mov  cx,8

lea    si,str3

lea    di,[bx].list.fild1

rep    movsb       ;заполнение поля fild1 третьего элемента

mov  es:[bx].next,nil             ; конец списка

mov  es:[bx].list.fild2,'$'

; Удалить второй элемент

mov  bx,top

delite es:[bx].next,%type aitem

mov  bx,top

mov  di,es:[bx].next

mov  ax,es:[di].next

mov  es:[bx].next,ax

; Печать списка

mov  bx,top                  ; Адрес текущего элемента списка

cont: cmp  bx,nil

jz       fin                        ; достигнут конец списка

lea    dx,[bx].list.fild1

push ds

push es

pop   ds

mov  ah,09h

int     21h   ;Печать тестового поля текущего элемента

pop   ds

mov  bx,es:[bx].next

jmp   cont

fin:    .exit  0

main endp

find   proc                              ; ax - размер требующейся памяти в байтах

SaveReg   <bx,cx,dx>

mov  cx,Heap_size/8  ; кол-во байт под статус

mov  bx,0

push ax                        ; сохранить объем памяти в стеке      

m0:   cmp  status[bx],0ffh     ; проверка на все единицы

jz       next1

mov  dl,1                      ; 1 в левый бит

m7:   test   status[bx],dl        ; проверка бита

jz       m1

pop   ax                        ; текущий бит равен 1 - заново

push ax

jmp   short m2

m1:   dec   ax                        ; найден еще один нулевой бит

jz       yes                      ; найден нужный объем памяти

m2:   shl    dl,1                      ; маска для следующего бита

jz       m3                       ; нужно перейти к новому байту

jmp   m7

next1:        pop   ax               ; восстановление размера

push ax

m3:   inc    bx                        ; увеличение номера байта

loop  m0                       ; цикл по всем байтам

jz       no

yes:  shl    bx,3            ; вычисление номера последнего бита

pop   cx                        ; считан размер

m4:   inc    bx                        ; добавить сдвиг внутри байта

shr    dl,1

jnz     m4

sub   bx,cx                   ; номер первого бита поля

mov  ax,bx

push ax

shr    bx,3                     ; номер байта

and   ax,07h                 ; и еще сдвиг на несколько бит

mov  ah,1

push cx

mov  cl,al

shl    ah,cl                    ; сдвиг маски в позицию первого бита

pop   cx

m6:   or      status[bx],ah   ; заполнение 1 маски отводимого поля

dec   cx

jz       m5

shl    ah,1

jnz     m6

inc    bx

mov  ah,1