Hello!
* It also support's sublists.
Information:; ---------------------------------------------------------------- ;
; This is: Win64 Linked List (NODELIST) NASM, GOLINK.
; Author: J.K. Encryptor256.
; Date: November 15, 2013.
; ---------------------------------------------------------------- ;
; Description:
;
; This is my recent version of Linked List's, named NODELIST.
; It's actually pretty easy.
; ---------------------------------------------------------------- ;
; Using:
;
; 1. Compiler:
; 1.1. NASM (The Netwide Assembler)
; 1.2. Web:(
http://nasm.us/)
;
; 2. Linker:
; 2.1. GoLink (Jeremy Gordon's Go Tools for Win32 and Win64)
; 2.2. Web:(
http://www.godevtool.com/)
;
; 3. Editor:
; 3.1. PSPad (Freeware Editor)
; 3.2. Web:(
http://www.pspad.com/en/)
;
; ---------------------------------------------------------------- ;
; How to compile and link,
;
; Easy, in the way, i did:
;
; 1. NASM: "nasm.exe -f win64 main.asm -o main.obj"
; Produces => main.obj: 5.66 KB (5,802 bytes)
;
; 2. GoLink: "golink.exe /entry main /console main.obj MSVCRT.dll"
; Produces => main.exe: 4.00 KB (4,096 bytes)
;
; ---------------------------------------------------------------- ;
; Linked list, named: NODELIST
; Linked list, node named: NODELISTNODE
; Procedures:
; 1. nodeListAdd
; 2. nodeListNodeNew
; 3. nodeListNew
; 4. nodeListPrint
; 5. nodeListCursorSet
; 6. nodeListCursorNext
; 7. nodeListCursorData
; 8. nodeListNodeDelete
; 9. nodeListDelete
; ---------------------------------------------------------------- ;
Data: These are structure offsets.
; ------------------------------------------- ;
; NODELIST Variables ;
; ------------------------------------------- ;
; NODELIST ;
NODELIST.FIRST equ (8*0) ;
NODELIST.LAST equ (8*1) ;
NODELIST.COUNT equ (8*2) ;
NODELIST_SIZE equ (8*3) ;
; ------------------------------------------- ;
; NODELISTNODE ;
NODELISTNODE.PARENT equ (8*0) ;
NODELISTNODE.PREV equ (8*1) ;
NODELISTNODE.TYPE equ (8*2) ;
NODELISTNODE.DATA equ (8*3) ;
NODELISTNODE.NEXT equ (8*4) ;
NODELISTNODE_SIZE equ (8*5) ;
; ------------------------------------------- ;
; NODELISTNODE list indicator ;
NODELISTNODE_TYPE_LIST equ (0xFFFF) ;
; ------------------------------------------- ;
Procedures: What kind'a procedures im using?
1. Ordinary: add, delete, ... procedures.
2. Extra: cursor procedures.
; ########################################### ;
; nodeListAdd: Procedure
;
; Usage:
; mov rcx,qword addrOfNodeList
; mov rdx,qword (nodeType)
; mov r8,qword (data)
; call nodeListNodeNew
;
; Returns nothing.
; Set's carry flag on error.
; Clear's carry flag on success.
;
; ########################################### ;
; nodeListNodeNew: Procedure
;
; Usage:
; call nodeListNodeNew
;
; Takes no arguments.
; Returns pointer to NODELISTNODE structure (RAX).
; Set's carry flag on error.
; Clear's carry flag on success.
;
; ########################################### ;
; nodeListNew: Procedure
;
; Usage:
; call nodeListNew
;
; Takes no arguments.
; Returns pointer to NODELIST structure (RAX).
; Set's carry flag on error.
; Clear's carry flag on success.
;
; ########################################### ;
; nodeListPrint: Procedure
;
; Usage:
; mov rcx,qword nodeListAddress
; call nodeListPrint
;
; Returns nothing.
; Set's carry flag on error.
; Clear's carry flag on success.
;
; ########################################### ;
; nodeListCursorSet: Procedure
;
; Uses: RCX, RBX
;
; Usage:
; mov rcx,qword nodeListAddress
; call nodeListCursorSet
;
; Returns nothing.
; Set's carry flag on error.
; Clear's carry flag on success.
; OnSuccess: Will store list.first into RBX.
;
; ########################################### ;
; nodeListCursorNext: Procedure
;
; Uses: RBX
;
; Usage:
; call nodeListCursorSet
;
; Returns nothing.
; Set's carry flag on error.
; Clear's carry flag on success.
; OnSuccess: Will store node.next into RBX.
;
; ########################################### ;
; nodeListCursorData: Procedure
;
; Uses: RBX, RAX, RCX
;
; Usage:
; call nodeListCursorData
;
; Returns nothing.
; Set's carry flag on error.
; Clear's carry flag on success.
; OnSuccess:
; Will get data from node(RBX).
; Will set node.type into RCX.
; Will set node.data into RAX.
;
; ########################################### ;
; nodeListNodeDelete: Procedure
;
; Usage:
; mov rcx,qword addrOfNodeListNode
; mov rdx,qword addrOfDeleteHandler
; call nodeListNodeDelete
;
; deleteHandler:
; ; rcx - node.type
; ; rdx - node.data
; ; If data is a pointer to buffer,
; ; that, could be deleted, by,
; ; providing a deletehandler to this
; ; procedure.
; ret
;
; Returns nothing.
; Set's carry flag on error.
; Clear's carry flag on success.
;
; ########################################### ;
; nodeListDelete: Procedure
;
; Usage:
; mov rcx,qword addrOfNodeList
; mov rdx,qword addrOfDeleteHandler
; call nodeListDelete
;
; deleteHandler:
; ; rcx - node.type
; ; rdx - node.data
; ; If data is a pointer to buffer,
; ; that, could be deleted, by,
; ; providing a deletehandler to this
; ; procedure.
; ret
;
; Returns deleted node count into RAX.
; Set's carry flag on error.
; Clear's carry flag on success.
;
; ########################################### ;
nodeListNodeDelete: This is the most longest, in bytes.
nodeListNodeDelete:
; Check argument - rcx:
cmp rcx,qword (0) ; For zero
je .earlyQuit
cmp qword [rcx+NODELISTNODE.PARENT],qword (0) ; For parent
je .earlyQuit
mov rax,qword [rcx+NODELISTNODE.PARENT] ; Check parent count > 0
cmp qword [rax+NODELIST.COUNT],qword (0)
jg .haveValidArgs
.earlyQuit:
stc
ret
.haveValidArgs:
; Save arguments:
mov qword [rsp+8*1],rcx; address of node list node
mov qword [rsp+8*2],rdx; address of delete handler
; mov qword [rsp+8*3],r8; (unused register)
; mov qword [rsp+8*4],r9; (unused register)
; ! (Note1) RBX, at first, is used as a, counter,
; of node's deleted.
; ! (Note2) RBX, also, is used to determine
; existence of node.prev's, node.next's.
; Create stack
push rbp
mov rbp,rsp
push rbx
lea rsp,[rsp-(8*5)]
; Init RBX counter (ref. Note1)
xor rbx,rbx
.check1:
; Check 1: If node.type is list, call => nodeListDelete
cmp qword [rcx+NODELISTNODE.TYPE],qword (NODELISTNODE_TYPE_LIST)
jl .check2
; rdx remains set
mov rcx,qword [rcx+NODELISTNODE.DATA]
call nodeListDelete
mov rbx,rax ; (ref. Note1)
jnc .checkDone
jmp .quit
.check2:
; Check 2: Pass node.type and node.data to delete handler
cmp rdx,qword (0)
je .checkDone
mov rax,rdx
mov rdx,qword [rcx+NODELISTNODE.DATA]
mov rcx,qword [rcx+NODELISTNODE.TYPE]
call rax
.checkDone:
mov rcx,qword [rsp+8*5+8*2+8*1]; Assign node to RCX
mov rdx,qword [rcx+NODELISTNODE.PARENT]; Assign node.parent to RDX
; Save RBX into RAX (ref. Note1)
mov rax,rbx
; Determine if node have prev or next (ref. Note2)
xor rbx,rbx
cmp qword [rcx+NODELISTNODE.PREV],qword (0)
je .prevChecked
inc rbx
.prevChecked:
cmp qword [rcx+NODELISTNODE.NEXT],qword (0)
je .nextChecked
inc rbx
inc rbx
.nextChecked:
; Operate by rbx
.rbxIs0:
cmp rbx,qword (0)
jne .rbxIs1
; node is the only one
mov qword [rdx+NODELIST.FIRST],qword (0)
mov qword [rdx+NODELIST.LAST],qword (0)
jmp .rbxIsDone
.rbxIs1:
cmp rbx,qword (1)
jne .rbxIs2
; node is last
mov r8,qword [rcx+NODELISTNODE.PREV]
mov qword [r8+NODELISTNODE.NEXT],qword (0)
mov qword [rdx+NODELIST.LAST],r8
jmp .rbxIsDone
.rbxIs2:
cmp rbx,qword (2)
jne .rbxIs3
; node is first
mov r8,qword [rcx+NODELISTNODE.NEXT]
mov qword [r8+NODELISTNODE.PREV],qword (0)
mov qword [rdx+NODELIST.FIRST],r8
jmp .rbxIsDone
.rbxIs3:
; node is in the middle
mov r8,qword [rcx+NODELISTNODE.PREV]
mov r9,qword [rcx+NODELISTNODE.NEXT]
mov qword [r8+NODELISTNODE.NEXT],r9
mov qword [r9+NODELISTNODE.PREV],r8
.rbxIsDone:
; Restore RBX into RAX (ref. Note1)
mov rbx,rax
inc rbx
; Decrease list.count
dec qword [rdx+NODELIST.COUNT]
; Release node memory
; rcx is already set
call free
; Set success
mov rax,rbx
clc
; Deallocate stack n quit
.quit:
lea rsp,[rsp+(8*5)]
pop rbx
pop rbp
ret
How to use:; ---------------------------------------------------------------- ;
; Example code info:
; 1. Create list, nr.1.
; 2. Add four items to list, nr.1.
; 3. Create list, nr.2.
; 4. Add list, nr.2., to list, nr.1.
; 5. Print list, nr.1.
; 6. Delete list, nr.1.
; -. Uses deleteHandler when deleting list's.
; -. Data n Type, can be accessed via deletionHandler,
; -. during deletion procedure.
; -. Uses createList procedure to create list, nr.2.
; ---------------------------------------------------------------- ;
; MAIN (Custom Procedure)
main:
push rbp
mov rbp,rsp
push rbx
lea rsp,[rsp-(8*15)]
; Create new list, nr. 1.
call nodeListNew
jc .quit
; Save list, nr. 1., address
mov qword [rsp+8*10],rax
; Add node to list, nr. 1.
mov rcx,qword [rsp+8*10]
mov rdx,qword 12
mov r8,qword 14
call nodeListAdd
jc .quit
; Add node to list, nr. 1.
mov rcx,qword [rsp+8*10]
mov rdx,qword 13
mov r8,qword 15
call nodeListAdd
jc .quit
; Add node to list, nr. 1.
mov rcx,qword [rsp+8*10]
mov rdx,qword 14
mov r8,qword 16
call nodeListAdd
jc .quit
; Add node to list, nr. 1.
mov rcx,qword [rsp+8*10]
mov rdx,qword 15
mov r8,qword 17
call nodeListAdd
jc .quit
; Create new list, nr. 2.
mov rcx,qword 10
mov rdx,qword 100
mov r8,qword 10
call createList
; Save list, nr. 2., address
mov qword [rsp+8*11],rax
; Add list, nr. 2, to list, nr. 1.
mov rcx,qword [rsp+8*10]
mov rdx,qword (NODELISTNODE_TYPE_LIST+1)
mov r8,qword [rsp+8*11]
call nodeListAdd
jc .quit
; Print list, nr. 1.
mov rcx,qword [rsp+8*10]
call nodeListPrint
jc .quit
; Delete list, nr. 1.
mov rcx,qword [rsp+8*10]
mov rdx,qword deleteHandler
call nodeListDelete
jc .quit
.quit:
lea rsp,[rsp+(8*15)]
pop rbx
pop rbp
ret
Output: (First list's, last item is another list)
[NODELIST:0x3EBE90]
--> 0. Type: 12, Data: 14 <--
--> 1. Type: 13, Data: 15 <--
--> 2. Type: 14, Data: 16 <--
--> 3. Type: 15, Data: 17 <--
--> 4. Type: NODELIST, Data: 0x3EBEB0 <--
[NODELIST:0x3EBEB0]
--> 0. Type: 10, Data: 100 <--
--> 1. Type: 11, Data: 100 <--
--> 2. Type: 12, Data: 100 <--
--> 3. Type: 13, Data: 100 <--
--> 4. Type: 14, Data: 100 <--
--> 5. Type: 15, Data: 100 <--
--> 6. Type: 16, Data: 100 <--
--> 7. Type: 17, Data: 100 <--
--> 8. Type: 18, Data: 100 <--
--> 9. Type: 19, Data: 100 <--
[/NODELIST:0x3EBEB0]
[/NODELIST:0x3EBE90]
DeleteHandler: Type: 12, Data: 14
DeleteHandler: Type: 13, Data: 15
DeleteHandler: Type: 14, Data: 16
DeleteHandler: Type: 15, Data: 17
DeleteHandler: Type: 10, Data: 100
DeleteHandler: Type: 11, Data: 100
DeleteHandler: Type: 12, Data: 100
DeleteHandler: Type: 13, Data: 100
DeleteHandler: Type: 14, Data: 100
DeleteHandler: Type: 15, Data: 100
DeleteHandler: Type: 16, Data: 100
DeleteHandler: Type: 17, Data: 100
DeleteHandler: Type: 18, Data: 100
DeleteHandler: Type: 19, Data: 100
Video:Watch source code and runtime video on youtube, named: "Win64 Linked List NODELIST NASM GOLINK".
Link:
http://youtu.be/cGZ2WJljJSYAttachment:Added attachment, named: "main.zip", which includes source code.
And that's it!
Encryptor256!!!