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

LIST.ASM

List


; =============================================================================
;
;                               Litos - List
;
; =============================================================================

		CODE_SECTION	32

; ------------- Macro - initialized list head (or initialized safe list entry)

%define		LISTHEAD dd	$,$

; ------------- Macro - initialized linked list entry
; %1 = pointer to next entry, %2 = pointer to previous entry

%macro		LINKEDLIST 2
		dd	%1,%2
%endmacro

; ------------- Macro - initialize list head (%1 = pointer to list head)

%macro		LISTINIT 1
		mov	[%1+LIST_Next],%1 ; next (first) entry in chain
		mov	[%1+LIST_Prev],%1 ; previous (last) entry in chain
%endmacro

; ------------- Macro - link two entries together (%1=1st entry, %2=2nd entry)

%macro		LINKLINK 2
		mov	[%1+LIST_Next],%2 ; link second entry after first one
		mov	[%2+LIST_Prev],%1 ; link first entry previous second
%endmacro

; ------------- Macro - add new entry into begin of list or after current entry
; %1 = list head or current entry, %2 = new entry, %3 = temporary register

%macro		LISTADD	3
		mov	%3,[%1+LIST_Next] ; get next (first) entry
		LINKLINK %1,%2		; link head/current with new entry
		LINKLINK %2,%3		; link new entry with next entry
%endmacro

; ------------- Macro - add new entry into end of list or before current entry
; %1 = list head or current entry, %2 = new entry, %3 = temporary register

%macro		LISTLAST 3
		mov	%3,[%1+LIST_Prev] ; get previous (last) entry
		LINKLINK %3,%2		; link new entry with previous entry
		LINKLINK %2,%1		; link head/current with new entry
%endmacro

; ------------- 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

; ------------- 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

; ------------- Macro - test if list is empty (output: ZY = list is empty)
; %1 = pointer to list head

%macro		LISTTEST 1
		cmp	[%1+LIST_Next],%1 ; check if list is empty
%endmacro

; ------------- Macro - mark safe list entry as empty (%1 = safe list entry)

%macro		LISTEMPTY 1
		mov	[%1+LIST_Next],%1 ; mark safe list entry as empty
%endmacro

; -----------------------------------------------------------------------------
;                           Initialize list head
; -----------------------------------------------------------------------------
; INPUT:	EBX = list head
; -----------------------------------------------------------------------------

ListInit:	LISTINIT ebx		; initialize list head
		ret

; -----------------------------------------------------------------------------
;                       Initialize safe list entry
; -----------------------------------------------------------------------------
; INPUT:	EBX = safe list entry
; NOTES:	Safe list entry is not in list if NEXT points to itself.
; -----------------------------------------------------------------------------

ListSafeInit:	LISTEMPTY ebx		; initialize safe list entry
		ret

; -----------------------------------------------------------------------------
;          Add new entry into begin of list or after current entry
; -----------------------------------------------------------------------------
; INPUT:	EAX = new entry
;		EBX = list head or current entry
; -----------------------------------------------------------------------------

ListAfter:
ListAdd:	push	ecx		; push ECX
		LISTADD	ebx,eax,ecx	; add new entry into list
		pop	ecx		; pop ECX
		ret

; -----------------------------------------------------------------------------
;         Add new safe entry into begin of list or after current entry
; -----------------------------------------------------------------------------
; INPUT:	EAX = new entry
;		EBX = list head or current entry
; NOTES:	Safe list entry is not in list if NEXT points to itself.
; -----------------------------------------------------------------------------

ListSafeAfter:
ListSafeAdd:	LISTTEST eax		; test if list entry is in a list
		jne	ListSafeAdd4	; list entry is already in a list
		push	ecx		; push ECX
		LISTADD	ebx,eax,ecx	; add new entry into list
		pop	ecx		; pop ECX
ListSafeAdd4:	ret

; -----------------------------------------------------------------------------
;           Add new entry into end of list or before current entry
; -----------------------------------------------------------------------------
; INPUT:	EAX = new entry
;		EBX = list head or current entry
; -----------------------------------------------------------------------------

ListBefore:
ListLast:	push	ecx		; push ECX
		LISTLAST ebx,eax,ecx	; add new entry into list
		pop	ecx		; pop ECX
		ret

; -----------------------------------------------------------------------------
;         Add new safe entry into end of list or before current entry
; -----------------------------------------------------------------------------
; INPUT:	EAX = new safe entry
;		EBX = list head or current entry
; NOTES:	Safe list entry is not in list if NEXT points to itself.
; -----------------------------------------------------------------------------

ListSafeBefore:
ListSafeLast:	LISTTEST eax		; test if list entry is in a list
		jne	ListSafeLast4	; list entry is already in a list
		push	ecx		; push ECX
		LISTLAST ebx,eax,ecx	; add new entry into list
		pop	ecx		; pop ECX
ListSafeLast4:	ret

; -----------------------------------------------------------------------------
;                   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) 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

; -----------------------------------------------------------------------------
;                  Delete (detach) list entry from the list
; -----------------------------------------------------------------------------
; 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

; -----------------------------------------------------------------------------
;                       Replace old entry with new one
; -----------------------------------------------------------------------------
; INPUT:	EAX = new entry
;		EBX = old entry
; -----------------------------------------------------------------------------

; ------------- Push registers

ListXchg:	push	ecx		; push ECX
		push	edx		; push EDX

; ------------- Exchange entries

		mov	ecx,[ebx+LIST_Prev] ; ECX <- get previous entry
		mov	edx,[ebx+LIST_Next] ; EDX <- get next entry
		mov	[eax+LIST_Prev],ecx ; link previous entry to new one
		mov	[eax+LIST_Next],edx ; link next entry to new one
		mov	[ecx+LIST_Next],eax ; link new entry to previous one
		mov	[edx+LIST_Prev],eax ; link new entry to next one

; ------------- Pop registers

		pop	edx		; pop EDX
		pop	ecx		; pop ECX
		ret

; -----------------------------------------------------------------------------
;                 Detach list chain and splice it with other list
; -----------------------------------------------------------------------------
; INPUT:	EAX = source list head (it will become empty)
;		EBX = destination list head
; -----------------------------------------------------------------------------

; ------------- Push registers

ListSplice:	push	ecx		; push ECX
		push	edx		; push EDX
		push	esi		; push ESI

; ------------- Check if source list is already empty

		cmp	eax,[eax+LIST_Next] ; is source list empty?
		je	ListSplice2	; source list is empty

; ------------- Detach list chain from source list

		mov	ecx,[eax+LIST_Next] ; ECX <- first entry of source list
		mov	edx,[eax+LIST_Prev] ; EDX <- last entry of source list
		mov	[eax+LIST_Next],eax ; close source list (first entry)
		mov	[eax+LIST_Prev],eax ; close source list (last entry)

; ------------- Atach list chain to destination list

		mov	esi,[ebx+LIST_Next] ; ESI <- first entry of destination
		mov	[ebx+LIST_Next],ecx ; link first entry to destination
		mov	[ecx+LIST_Prev],ebx ; link destination to first entry
		mov	[edx+LIST_Next],esi ; link 1st entry 2 to last entry 1
		mov	[esi+LIST_Prev],edx ; link last entry 1 to 1st entry 2

; ------------- Pop registers

ListSplice2:	pop	esi		; pop ESI
		pop	edx		; pop EDX
		pop	ecx		; pop ECX
		ret

Back to source browser