Obsah / Utility / LIST / Zrušení prvku ze seznamu
Zdrojový kód:
INCLUDE\UTIL\LIST.INC, UTIL\LIST.ASM
Zrušení
prvku ze seznamu
Při uvolnění prvku
ze seznamu je potřeba zajistit vzájemné propojení ukazatelů
předcházející a následující položky seznamu. U
bezpečného seznamu je navíc potřeba inicializovat ukazatel
odpojené položky jako příznak, že položka nepatří do
žádného seznamu.
; ------------- Macro - delete (detach) entry from the list
; %1 = entry to delete, %2 and %3 = temporary registers
; %1 and %3 can be the same, in that case content of %1 will be changed
; On output: %2 = old previous entry, %3 = old next entry
%macro LISTDEL 3
mov %2,[%1+LIST_Prev] ; get previous entry
mov %3,[%1+LIST_Next] ; get next entry
LINKLINK %2,%3 ; link previous entry with next entry
%endmacro
|
Makro LISTDEL zajistí
uvolnění položky ze seznamu. Prvním parametrem makra je
ukazatel na rušenou (uvolňovanou) položku, dalšími dvěma
parametry jsou registry použité jako přechodné registry. Do
prvního přechodného registru je v první instrukci makra
načten ukazatel na předcházející položku LIST_Prev. Do
druhého přechodného registru je načten ukazatel na
následující položku LIST_Next. Předchozí a následující
položky jsou následujícím makrem LINKLINK vzájemně
propojeny, čímž dojde k odpojení prvku ze seznamu.
; -----------------------------------------------------------------------------
; Delete (detach) list entry from the list
; -----------------------------------------------------------------------------
; INPUT: EAX = entry to delete
; -----------------------------------------------------------------------------
ListDel: push ebx ; push EBX
push ecx ; push ECX
LISTDEL eax,ebx,ecx ; delete list entry
pop ecx ; pop ECX
pop ebx ; pop EBX
ret
; -----------------------------------------------------------------------------
; Delete (detach) list entry from the list (using EBX registry)
; -----------------------------------------------------------------------------
; INPUT: EBX = entry to delete
; -----------------------------------------------------------------------------
ListDelEBX: push eax ; push EAX
push ecx ; push ECX
LISTDEL ebx,eax,ecx ; delete list entry
pop ecx ; pop ECX
pop eax ; pop EAX
ret
; -----------------------------------------------------------------------------
; Delete (detach) list entry from the list (using EDX registry)
; -----------------------------------------------------------------------------
; INPUT: EDX = entry to delete
; -----------------------------------------------------------------------------
ListDelEDX: push ebx ; push EBX
push ecx ; push ECX
LISTDEL edx,ebx,ecx ; delete list entry
pop ecx ; pop ECX
pop ebx ; pop EBX
ret
|
Makro LISTDEL je použito ve
funkci ListDel, která zajistí uvolnění prvku ze seznamu,
jehož ukazatel na popisovač seznamu je funkci předán v
registru EAX. Funkce používá přechodné registry EBX a ECX,
proto jsou jejich původní hodnoty uchovány instrukcemi
PUSH/POP. Funkce ListDelEBX a ListDelEDX jsou obměnami funkce
ListDel, ukazatel na rušenou položku je předán v registrech
EBX resp. EDX.
; ------------- Macro - detach entry from the previous entry
; %1 = entry to delete, %2 = previous entry, %3 = temporary registers
%macro LISTDELPREV 3
mov %3,[%1+LIST_Next] ; get next entry
LINKLINK %2,%3 ; link previous entry with next entry
%endmacro
|
Makro LISTDELPREV je
zjednodušenou variantou makra LISTDEL v případě, že ukazatel
na předcházející položku je již načten v registru, který
je předán jako druhý parametr makra.
; -----------------------------------------------------------------------------
; Delete (detach) safe list entry from the list
; -----------------------------------------------------------------------------
; INPUT: EAX = safe entry to delete
; NOTES: Safe list entry is not in list if NEXT points to itself.
; -----------------------------------------------------------------------------
ListSafeDel: LISTTEST eax ; test if list entry is in a list
je ListSafeDel4 ; list entry is not in a list
push ebx ; push EBX
push ecx ; push ECX
LISTDEL eax,ebx,ecx ; delete list entry
pop ecx ; pop ECX
pop ebx ; pop EBX
LISTEMPTY eax ; mark entry as empty
ListSafeDel4: ret
|
Funkce ListSafeDel je
variantou funkce ListDel pro bezpečný seznam. Položka, která
má být zrušena, je nejdříve zkontrolována, zda je
připojena k seznamu. Není-li připojena k žádnému seznamu,
nic se neprovede a funkce se předčasně ukončí. Nelze
ověřit, zda položka patří konkrétně do tohoto seznamu, ze
kterého je rušena. Po uvolnění položky ze seznamu je
položka označena jako prázdná (tj. nepřipojena k žádnému
seznamu) pomocí makra LISTEMPTY.
Obsah / Utility / LIST / Zrušení prvku ze seznamu