Tvůrce webu je i pro tebe! Postav třeba web. Bez grafika. Bez kodéra. Hned.
wz

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