Author Topic: Win64 Linked List (NODELIST) NASM, GOLINK  (Read 5008 times)

Offline encryptor256

  • Full Member
  • **
  • Posts: 250
  • Country: lv
  • Win64 .
    • On Youtube: encryptor256
Win64 Linked List (NODELIST) NASM, GOLINK
« on: November 15, 2013, 11:11:15 AM »
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.

Code: [Select]
; ------------------------------------------- ;
; 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.

Code: [Select]
; ########################################### ;
; 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.

Code: [Select]
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.
; ---------------------------------------------------------------- ;

Code: [Select]
; 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)

Code: [Select]
[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/cGZ2WJljJSY

Attachment:

Added attachment, named: "main.zip", which includes source code.

And that's it!
Encryptor256!!!
Encryptor256's Investigation \ Research Department.

Offline encryptor256

  • Full Member
  • **
  • Posts: 250
  • Country: lv
  • Win64 .
    • On Youtube: encryptor256
Re: Win64 Linked List (NODELIST) NASM, GOLINK
« Reply #1 on: November 16, 2013, 05:26:26 PM »
Hello!

Today i created a better one.
Data structures are just like in C++ OOP with inheritance. :)

nodebase is inherited by nodedata and nodelist.

This is how you do it, in NASM:

* The key to understand it, is to look at offsets.

Code: [Select]
; -----------------------------------------------------------;
      ; node n nodelist, data structure offsets n constants

      ; node base
            nodebase.parent   equ (8*0)
            nodebase.type     equ (8*1)
            nodebase.prev     equ (8*2)
            nodebase.next     equ (8*3)

      ; node data:

            nodedata.data         equ (8*4)
            nodedata_size         equ (8*5)

      ; node list:

            nodelist.first equ (8*4)
            nodelist.last equ (8*5)
            nodelist.count equ (8*6)
            nodelist_size equ (8*7)

            node_type_list equ (0xFFFF)

Procedures, found in source code:
  • nodelist.print
  • nodelist.getList
  • deletehandler
  • main
  • nodedata.new
  • nodelist.new
  • nodelist.add.nodebase
  • sysAllocateMemory
  • nodelist.cursor.set.on.first
  • nodelist.cursor.set.on.last
  • nodelist.cursor.next
  • nodelist.cursor.prev
  • nodebase.remove
  • nodebase.delete

This is source code output, pretty interesting:

Code: [Select]


[[[ --- FIRST --- ]]]
 * Create list A.
 * Print list A.

[nodelist addr: 4770624, type: 65535]
     [node] type: 10, data: 20 [/node]
     [node] type: 11, data: 21 [/node]
     [node] type: 12, data: 22 [/node]
     [node] type: 13, data: 23 [/node]
     [node] type: 14, data: 24 [/node]
     [node] type: 15, data: 25 [/node]
     [node] type: 16, data: 26 [/node]
     [node] type: 17, data: 27 [/node]
     [node] type: 18, data: 28 [/node]
     [node] type: 19, data: 29 [/node]
[/nodelist addr: 4770624, type: 65535]

[[[ --- SECOND --- ]]]
 * Create list B.
 * Add list B. to list A.
 * Print list A.

[nodelist addr: 4770624, type: 65535]
     [node] type: 10, data: 20 [/node]
     [node] type: 11, data: 21 [/node]
     [node] type: 12, data: 22 [/node]
     [node] type: 13, data: 23 [/node]
     [node] type: 14, data: 24 [/node]
     [node] type: 15, data: 25 [/node]
     [node] type: 16, data: 26 [/node]
     [node] type: 17, data: 27 [/node]
     [node] type: 18, data: 28 [/node]
     [node] type: 19, data: 29 [/node]
     [nodelist addr: 4770688, type: 65536]
          [node] type: 55, data: 80 [/node]
          [node] type: 56, data: 81 [/node]
          [node] type: 57, data: 82 [/node]
          [node] type: 58, data: 83 [/node]
          [node] type: 59, data: 84 [/node]
          [node] type: 60, data: 85 [/node]
          [node] type: 61, data: 86 [/node]
          [node] type: 62, data: 87 [/node]
          [node] type: 63, data: 88 [/node]
          [node] type: 64, data: 89 [/node]
     [/nodelist addr: 4770688, type: 65536]
[/nodelist addr: 4770624, type: 65535]

[[[ --- THIRD --- ]]]
 * Delete list A.

<deleteHandler> type: 10, data: 20 </deleteHandler>
<deleteHandler> type: 11, data: 21 </deleteHandler>
<deleteHandler> type: 12, data: 22 </deleteHandler>
<deleteHandler> type: 13, data: 23 </deleteHandler>
<deleteHandler> type: 14, data: 24 </deleteHandler>
<deleteHandler> type: 15, data: 25 </deleteHandler>
<deleteHandler> type: 16, data: 26 </deleteHandler>
<deleteHandler> type: 17, data: 27 </deleteHandler>
<deleteHandler> type: 18, data: 28 </deleteHandler>
<deleteHandler> type: 19, data: 29 </deleteHandler>
<deleteHandler> type: 55, data: 80 </deleteHandler>
<deleteHandler> type: 56, data: 81 </deleteHandler>
<deleteHandler> type: 57, data: 82 </deleteHandler>
<deleteHandler> type: 58, data: 83 </deleteHandler>
<deleteHandler> type: 59, data: 84 </deleteHandler>
<deleteHandler> type: 60, data: 85 </deleteHandler>
<deleteHandler> type: 61, data: 86 </deleteHandler>
<deleteHandler> type: 62, data: 87 </deleteHandler>
<deleteHandler> type: 63, data: 88 </deleteHandler>
<deleteHandler> type: 64, data: 89 </deleteHandler>

Process completed, Exit Code 20.
Execution time: 00:00.156

Exit Code 20, means it has deleted 20 nodes, actually it released 20 nodes and 2x lists, lists are excluded, because they are containers, not a direct meaning of a node.

When deleting a list, i pass, a deleteHandler, so, when node is being deleted, then its type and data are sent to deleteHandler. This is useful if that node data is a pointer and must be freed by the user.

Attachment:

I create a project with:

;     3.1. PSPad (Freeware Editor)
;     3.2. Web:(http://www.pspad.com/en/)

Added an attachment, named: "pspad_project_linkedlist.zip", which includes all project files, possibility to replicate the "output" mentioned above.

* If you know how these linked list data structures work, you can easely build a torrent file, bencoded string parser.

Bye,
Encryptor!!!
« Last Edit: November 16, 2013, 05:28:57 PM by encryptor256 »
Encryptor256's Investigation \ Research Department.

Offline encryptor256

  • Full Member
  • **
  • Posts: 250
  • Country: lv
  • Win64 .
    • On Youtube: encryptor256
Re: Win64 Linked List (NODELIST) NASM, GOLINK
« Reply #2 on: November 27, 2013, 07:26:05 PM »
Hello!

Today i updated to new one, even better, smarter, clever one.

New:
  • Data structure nodelistex
  • Traverse tree by query procedure (handler required)
  • Two procedures - nodelistex.new, nodelistex.query
  • All procedures are now aligned to 16 byte boundaries
  • Replaced all "register compare against zero" with test instruction
  • All procedures experienced at least some changes

Query handler procedure is programmable.
Full description about procedures can be found in source code "inc" files.
Using PsPad code editor, mentioned at prev post.

Data structures:
Code: [Select]
; nodelist:
      ; -----------------------------------------------------------;

      ; node (base node)
            node.parent equ (8*0)
            node.type equ (8*1)
            node.prev equ (8*2)
            node.next equ (8*3)

      ; node data: inherits node

            nodedata.data equ (8*4)
            nodedata_size equ (8*5)

      ; node list: inherits node

            nodelist.first equ (8*4)
            nodelist.last equ (8*5)
            nodelist.count equ (8*6)
            nodelist_size equ (8*7)

      ; node list ex: inherits nodelist

            nodelistex.deletehandler equ (8*7)
            nodelistex.queryhandler equ (8*8)
            nodelistex_size equ (8*9)

      ; node list indicator:

            ; If node type is greater or equal than,
            ; node list idicator, then, node is,
            ; cosidered to be a node with,
            ; nodelist base structure.
            node_type_list equ (0x0FFFFF)

      ; node list ex indicator:

            ; If node type is greater or equal than,
            ; node listex idicator, then, node is,
            ; cosidered to be a node with,
            ; nodelistex base structure.
            node_type_listex equ (0x1FFFFF)

      ; node data indicator:
            ; If node type is equal to
            ; node data idicator, then, node is,
            ; cosidered to be a node with,
            ; nodedata base structure.
            node_type_data equ (0x010000)

Current procedures:
Code: [Select]
global node.new,\
            nodelist.add.node, nodelist.add.nodedata,\
            nodelist.cursor.set.on.first, nodelist.cursor.set.on.last,\
            nodelist.cursor.next, nodelist.cursor.prev,\
            node.remove, node.delete,\
            nodelistex.new, nodelistex.query

These two are completely new:
Code: [Select]
; -----------------------------------------------------------;
;
; Procedure: nodelistex.new
;
; Create's new a nodelistex.
; RCX - delete handler address.
; RDX - get handler address.
;
; Usage:
;
;           ; Create nodelistex node
;           mov rcx,qword delHandlerAddress
;           mov rdx,qword getHandlerAddress
;           call nodelistex.new
;           jc .quitError
;
; Returns a pointer to node into RAX.
; Set's carry flag on error.
; Clear's carry flag on success.
;
; -----------------------------------------------------------;
;
; Procedure: nodelistex.query
;
; RCX - nodelistex address
; RDX - data1
; R8 - data2
; R9 - data3
;
; Usage:
;
;             ; Create new list
;             mov rcx,deletehandler
;             mov rdx,queryhandler
;             call nodelistex.new
;             jc .quit
;
;             mov rcx,rax
;             xor rdx,rdx
;             xor r8,r8
;             xor r9,r9
;             call nodelistex.query
;             jc .noData
;
; Returns value by
; Procedure: queryhandler.
; Set's carry flag on error.
; Clear's carry flag on success.
;
; -----------------------------------------------------------;

Query procedure:
Code: [Select]
; -----------------------------------------------------------;
;
; Procedure: queryhandler (User Defined)
;
; RCX - node
; RDX - data (If modify, use R12)
; R8 - data (If modify, use R13)
; R9 - data (If modify, use R14)
;
; Caller has provided with three volatile registers: R12-14.
; Modify them, will modify incoming arguments RDX, R8, R9.
;
; This procedure will return result for nodelistex.query.
;
; ! Set carry flag to continue query further:
; If node is list type,
; then, returned RAX indicates, what node to pick next:
; 0 -> first
; 1 -> last
; 2 -> next
; 4 -> prev
; 8 -> parent
; If node is non-list type,
; then, returned RAX indicates, what node to pick next:
; 0 -> next
; 1 -> prev
; 2 -> parent
;
; ! Clear carry flag to stop query further:
; Returns result in RAX on success.
; On success, register values are set:
;     1. RCX - nodelistex address (remains set)
;     2. RDX - R12 (changed or unchanged data)
;     3. R8 - R13 (changed or unchanged data)
;     4. R9 - R14 (changed or unchanged data)
;
; EXAMPLE:
; Traverse list from bottom and print
; node address and modified arguments.
;
; ...
; txt_text: db 10,".query. %d %d %d %d",0
; ...
;
;
; align 16
; queryhandler:
;
;       ; Save args
;       mov qword [rsp+8*1],rcx;
;       mov qword [rsp+8*2],rdx;
;       mov qword [rsp+8*3],r8;
;       mov qword [rsp+8*4],r9;
;
;       ; Create stack
;       push rbp
;       mov rbp,rsp
;       push rbx
;       lea rsp,[rsp-(8*5)]
;
;       mov qword [rsp+8*4],r9
;       mov r9,r8
;       mov r8,rdx
;       mov rdx,rcx
;       mov rcx,qword txt_text
;       call printf
;
;       inc r12
;       mov r13,10
;       inc r14
;
;       xor rax,rax
;       mov rax,1
;       stc
; .quit:
;       ; Clear stack n quit
;       lea rsp,[rsp+(8*5)]
;       pop rbx
;       pop rbp
;       ret
;
; ...
; txt_format_dhandler: db 10,"<deleteHandler> type: %d, data: %d </deleteHandler>",0
; ...
; align 16
; deletehandler:
;       lea rsp,[rsp-8*5]
;
;       mov r9,qword [rcx+nodedata.data]
;       mov r8,qword [rcx+node.type]
;       mov rdx,qword txt_format_dhandler
;       mov rcx,qword buffer
;       call sprintf
;       mov rcx,qword buffer
;       call printf
;
;       lea rsp,[rsp+8*5]
;       ret
;
; -----------------------------------------------------------;

Source code output:
Code: [Select]

[code begin]


; Create main list

[nodelist addr: 4107856, type: 2097151]
     [node addr: 4114064, type: 65536, parent: 4107856] data: 10 [/node]
     [node addr: 4114112, type: 65536, parent: 4107856] data: 11 [/node]
     [node addr: 4114160, type: 65536, parent: 4107856] data: 12 [/node]
     [node addr: 4114208, type: 65536, parent: 4107856] data: 13 [/node]
     [node addr: 4114256, type: 65536, parent: 4107856] data: 14 [/node]
     [node addr: 4114304, type: 65536, parent: 4107856] data: 15 [/node]
     [node addr: 4114352, type: 65536, parent: 4107856] data: 16 [/node]
     [node addr: 4114400, type: 65536, parent: 4107856] data: 17 [/node]
     [node addr: 4114448, type: 65536, parent: 4107856] data: 18 [/node]
     [node addr: 4114496, type: 65536, parent: 4107856] data: 19 [/node]
[/nodelist addr: 4107856, type: 2097151]

; Create secondary list

[nodelist addr: 4107936, type: 2097151]
     [node addr: 4114544, type: 65536, parent: 4107936] data: 20 [/node]
     [node addr: 4114592, type: 65536, parent: 4107936] data: 21 [/node]
     [node addr: 4114640, type: 65536, parent: 4107936] data: 22 [/node]
     [node addr: 4114688, type: 65536, parent: 4107936] data: 23 [/node]
     [node addr: 4114736, type: 65536, parent: 4107936] data: 24 [/node]
     [node addr: 4114784, type: 65536, parent: 4107936] data: 25 [/node]
     [node addr: 4114832, type: 65536, parent: 4107936] data: 26 [/node]
     [node addr: 4114880, type: 65536, parent: 4107936] data: 27 [/node]
     [node addr: 4114928, type: 65536, parent: 4107936] data: 28 [/node]
     [node addr: 4114976, type: 65536, parent: 4107936] data: 29 [/node]
[/nodelist addr: 4107936, type: 2097151]

; Add secondary list to main list

[nodelist addr: 4107856, type: 2097151]
     [node addr: 4114064, type: 65536, parent: 4107856] data: 10 [/node]
     [node addr: 4114112, type: 65536, parent: 4107856] data: 11 [/node]
     [node addr: 4114160, type: 65536, parent: 4107856] data: 12 [/node]
     [node addr: 4114208, type: 65536, parent: 4107856] data: 13 [/node]
     [node addr: 4114256, type: 65536, parent: 4107856] data: 14 [/node]
     [node addr: 4114304, type: 65536, parent: 4107856] data: 15 [/node]
     [node addr: 4114352, type: 65536, parent: 4107856] data: 16 [/node]
     [node addr: 4114400, type: 65536, parent: 4107856] data: 17 [/node]
     [node addr: 4114448, type: 65536, parent: 4107856] data: 18 [/node]
     [node addr: 4114496, type: 65536, parent: 4107856] data: 19 [/node]
     [nodelist addr: 4107936, type: 2097151]
          [node addr: 4114544, type: 65536, parent: 4107936] data: 20 [/node]
          [node addr: 4114592, type: 65536, parent: 4107936] data: 21 [/node]
          [node addr: 4114640, type: 65536, parent: 4107936] data: 22 [/node]
          [node addr: 4114688, type: 65536, parent: 4107936] data: 23 [/node]
          [node addr: 4114736, type: 65536, parent: 4107936] data: 24 [/node]
          [node addr: 4114784, type: 65536, parent: 4107936] data: 25 [/node]
          [node addr: 4114832, type: 65536, parent: 4107936] data: 26 [/node]
          [node addr: 4114880, type: 65536, parent: 4107936] data: 27 [/node]
          [node addr: 4114928, type: 65536, parent: 4107936] data: 28 [/node]
          [node addr: 4114976, type: 65536, parent: 4107936] data: 29 [/node]
     [/nodelist addr: 4107936, type: 2097151]
[/nodelist addr: 4107856, type: 2097151]

; Create new empty list

[nodelist addr: 4108016, type: 2097151]
[/nodelist addr: 4108016, type: 2097151]

; Add empty list to main list

[nodelist addr: 4107856, type: 2097151]
     [node addr: 4114064, type: 65536, parent: 4107856] data: 10 [/node]
     [node addr: 4114112, type: 65536, parent: 4107856] data: 11 [/node]
     [node addr: 4114160, type: 65536, parent: 4107856] data: 12 [/node]
     [node addr: 4114208, type: 65536, parent: 4107856] data: 13 [/node]
     [node addr: 4114256, type: 65536, parent: 4107856] data: 14 [/node]
     [node addr: 4114304, type: 65536, parent: 4107856] data: 15 [/node]
     [node addr: 4114352, type: 65536, parent: 4107856] data: 16 [/node]
     [node addr: 4114400, type: 65536, parent: 4107856] data: 17 [/node]
     [node addr: 4114448, type: 65536, parent: 4107856] data: 18 [/node]
     [node addr: 4114496, type: 65536, parent: 4107856] data: 19 [/node]
     [nodelist addr: 4107936, type: 2097151]
          [node addr: 4114544, type: 65536, parent: 4107936] data: 20 [/node]
          [node addr: 4114592, type: 65536, parent: 4107936] data: 21 [/node]
          [node addr: 4114640, type: 65536, parent: 4107936] data: 22 [/node]
          [node addr: 4114688, type: 65536, parent: 4107936] data: 23 [/node]
          [node addr: 4114736, type: 65536, parent: 4107936] data: 24 [/node]
          [node addr: 4114784, type: 65536, parent: 4107936] data: 25 [/node]
          [node addr: 4114832, type: 65536, parent: 4107936] data: 26 [/node]
          [node addr: 4114880, type: 65536, parent: 4107936] data: 27 [/node]
          [node addr: 4114928, type: 65536, parent: 4107936] data: 28 [/node]
          [node addr: 4114976, type: 65536, parent: 4107936] data: 29 [/node]
     [/nodelist addr: 4107936, type: 2097151]
     [nodelist addr: 4108016, type: 2097151]
     [/nodelist addr: 4108016, type: 2097151]
[/nodelist addr: 4107856, type: 2097151]

; Create new data node


; Add data node to main list


; Print main list

[nodelist addr: 4107856, type: 2097151]
     [node addr: 4114064, type: 65536, parent: 4107856] data: 10 [/node]
     [node addr: 4114112, type: 65536, parent: 4107856] data: 11 [/node]
     [node addr: 4114160, type: 65536, parent: 4107856] data: 12 [/node]
     [node addr: 4114208, type: 65536, parent: 4107856] data: 13 [/node]
     [node addr: 4114256, type: 65536, parent: 4107856] data: 14 [/node]
     [node addr: 4114304, type: 65536, parent: 4107856] data: 15 [/node]
     [node addr: 4114352, type: 65536, parent: 4107856] data: 16 [/node]
     [node addr: 4114400, type: 65536, parent: 4107856] data: 17 [/node]
     [node addr: 4114448, type: 65536, parent: 4107856] data: 18 [/node]
     [node addr: 4114496, type: 65536, parent: 4107856] data: 19 [/node]
     [nodelist addr: 4107936, type: 2097151]
          [node addr: 4114544, type: 65536, parent: 4107936] data: 20 [/node]
          [node addr: 4114592, type: 65536, parent: 4107936] data: 21 [/node]
          [node addr: 4114640, type: 65536, parent: 4107936] data: 22 [/node]
          [node addr: 4114688, type: 65536, parent: 4107936] data: 23 [/node]
          [node addr: 4114736, type: 65536, parent: 4107936] data: 24 [/node]
          [node addr: 4114784, type: 65536, parent: 4107936] data: 25 [/node]
          [node addr: 4114832, type: 65536, parent: 4107936] data: 26 [/node]
          [node addr: 4114880, type: 65536, parent: 4107936] data: 27 [/node]
          [node addr: 4114928, type: 65536, parent: 4107936] data: 28 [/node]
          [node addr: 4114976, type: 65536, parent: 4107936] data: 29 [/node]
     [/nodelist addr: 4107936, type: 2097151]
     [nodelist addr: 4108016, type: 2097151]
     [/nodelist addr: 4108016, type: 2097151]
     [node addr: 4115024, type: 65536, parent: 4107856] data: 27015 [/node]
[/nodelist addr: 4107856, type: 2097151]

; Basic query procedure example

.query. 4107856 0 0 0
.query. 4115024 1 10 1
.query. 4108016 2 10 2
.query. 4107936 3 10 3
.query. 4114976 4 10 4
.query. 4114928 5 10 5
.query. 4114880 6 10 6
.query. 4114832 7 10 7
.query. 4114784 8 10 8
.query. 4114736 9 10 9
.query. 4114688 10 10 10
.query. 4114640 11 10 11
.query. 4114592 12 10 12
.query. 4114544 13 10 13
.query. 4114496 14 10 14
.query. 4114448 15 10 15
.query. 4114400 16 10 16
.query. 4114352 17 10 17
.query. 4114304 18 10 18
.query. 4114256 19 10 19
.query. 4114208 20 10 20
.query. 4114160 21 10 21
.query. 4114112 22 10 22
.query. 4114064 23 10 23

; Delete main list

[deletingnode addr: 4114064, type: 65536] data: 10 [/deletingnode]
[deletingnode addr: 4114112, type: 65536] data: 11 [/deletingnode]
[deletingnode addr: 4114160, type: 65536] data: 12 [/deletingnode]
[deletingnode addr: 4114208, type: 65536] data: 13 [/deletingnode]
[deletingnode addr: 4114256, type: 65536] data: 14 [/deletingnode]
[deletingnode addr: 4114304, type: 65536] data: 15 [/deletingnode]
[deletingnode addr: 4114352, type: 65536] data: 16 [/deletingnode]
[deletingnode addr: 4114400, type: 65536] data: 17 [/deletingnode]
[deletingnode addr: 4114448, type: 65536] data: 18 [/deletingnode]
[deletingnode addr: 4114496, type: 65536] data: 19 [/deletingnode]
[deletingnode addr: 4114544, type: 65536] data: 20 [/deletingnode]
[deletingnode addr: 4114592, type: 65536] data: 21 [/deletingnode]
[deletingnode addr: 4114640, type: 65536] data: 22 [/deletingnode]
[deletingnode addr: 4114688, type: 65536] data: 23 [/deletingnode]
[deletingnode addr: 4114736, type: 65536] data: 24 [/deletingnode]
[deletingnode addr: 4114784, type: 65536] data: 25 [/deletingnode]
[deletingnode addr: 4114832, type: 65536] data: 26 [/deletingnode]
[deletingnode addr: 4114880, type: 65536] data: 27 [/deletingnode]
[deletingnode addr: 4114928, type: 65536] data: 28 [/deletingnode]
[deletingnode addr: 4114976, type: 65536] data: 29 [/deletingnode]
[deletingnode addr: 4115024, type: 65536] data: 27015 [/deletingnode]

[code end]

Process completed, Exit Code 0.
Execution time: 00:00.578

Pretty darn cool! :D

Added attachment: pspad_dds_sys.zip
  • sys library, used by dds
  • dds library
sys - system.
dds - dynamic data structures (linked list - node list).
dds project is example project which produced "source code output" above.

Bye, Encryptor256!!!
Encryptor256's Investigation \ Research Department.

Offline encryptor256

  • Full Member
  • **
  • Posts: 250
  • Country: lv
  • Win64 .
    • On Youtube: encryptor256
Re: Win64 Linked List (NODELIST) NASM, GOLINK
« Reply #3 on: December 13, 2013, 06:28:33 PM »
Hello!

This is not a joke.  ;D

Today i updated dds - dynamic data structures library to a new version., again.
This version is better than previous ones.

What's new:
  • All dds code is new, reworked sys library
  • Some functions saves and restores all argument registers

Current procedures:
  • node.new
  • node.add
  • node.remove
  • node.delete
  • node.query
  • node.queryprocedure (used in example code)
  • dbgPrintList (used in example code, print's a list, depth supportive)
  • dbgCreateList (used in example code, creates new list: empty or with nodes)

+ sys library procedures:
  • sysmemcheck
  • sysmalloc
  • sysfree
  • sysHash
  • sysbatohs ("sysByteArrayToHexString")
  • sysrdfc ("sysReadFileContent")

Procedure description, example usage:
  • for sys procedures consult file: sys.inc
  • for dds procedures consult file: dds.inc

Current data structures:
Code: [Select]
; node - base node
      node.parent equ (8*0)
      node.type   equ (8*1)
      node.prev   equ (8*2)
      node.next   equ (8*3)

      ; nodedata - data node inherits base node
      nodedata.data equ (8*4)
      nodedata_size equ (8*5)

      ; nodelist - list node inherits base node
      nodelist.first    equ (8*4)
      nodelist.last     equ (8*5)
      nodelist.count    equ (8*6)
      nodelist_size     equ (8*7)

      ; node data indicator
      node_type_data    equ (0x00FFFFFF)

      ; node list indicator
      node_type_list    equ (0x01000000)

      ; node with type value less equal than "node_type_data",
      ; is considered to be a data node.

      ; node with type value greater equal than "node_type_list",
      ; is considered to be a list node.

Example code, runtime test:
Code: [Select]
; ------------------------------------------------------------------------------
;
; -> PROCEDURE: main
;
; ------------------------------------------------------------------------------
align 16
main:
      ; Create stack
      push rbp
      mov rbp,rsp
      push rbx
      push r12
      push r13
      lea rsp,[rsp-(8*31)]

      ; Print info
      mov rcx,qword txt_code_begin
      call printf

      ; Create basic list A.
      mov rcx,10
      mov rdx,20
      call dbgCreateList
      jc .quit

      ; Save list A. address
      mov qword [rsp+8*20],rax

      ; Print list A.
      mov rcx,qword [rsp+8*20]
      xor rdx,rdx
      call dbgPrintList
      jc .quit

      ; Query nodes from list A.
      mov rcx,qword [rsp+8*20]
      mov rdx,qword node.queryprocedure
      xor r8,r8
      xor r9,r9
      call node.query

      ; Delete, list A., first node
      mov rcx,qword [rsp+8*20]
      mov rcx,qword [rcx+nodelist.first]
      xor rdx,rdx
      call node.delete
      jc .quit

      ; Delete, list A., last node
      mov rcx,qword [rsp+8*20]
      mov rcx,qword [rcx+nodelist.last]
      call node.delete
      jc .quit

      ; Delete, list A., first->next->next node
      mov rcx,qword [rsp+8*20]
      mov rcx,qword [rcx+nodelist.first]
      mov rcx,qword [rcx+node.next]
      mov rcx,qword [rcx+node.next]
      call node.delete
      jc .quit

      ; Delete, list A., last->prev->prev node
      mov rcx,qword [rsp+8*20]
      mov rcx,qword [rcx+nodelist.last]
      mov rcx,qword [rcx+node.prev]
      mov rcx,qword [rcx+node.prev]
      call node.delete
      jc .quit

      ; Print list A.
      mov rcx,qword [rsp+8*20]
      xor rdx,rdx
      call dbgPrintList
      jc .quit

      ; Create basic list B.
      mov rcx,15
      mov rdx,400
      call dbgCreateList
      jc .quit

      ; Save list B. address
      mov qword [rsp+8*21],rax

      ; Add list B. to list A.
      mov rcx,qword [rsp+8*20]
      mov rdx,qword [rsp+8*21]
      xor r8,r8
      call node.add
      jc .quit

      ; Create empty list C.
      mov rcx,0
      mov rdx,0
      call dbgCreateList
      jc .quit

      ; Save list C. address
      mov qword [rsp+8*22],rax

      ; Add list C. to list B.
      mov rcx,qword [rsp+8*21]
      mov rdx,qword [rsp+8*22]
      xor r8,r8
      call node.add
      jc .quit

      ; Print list A.
      mov rcx,qword [rsp+8*20]
      xor rdx,rdx
      call dbgPrintList
      jc .quit

      ; Delete list A.
      mov rcx,qword [rsp+8*20]
      xor rdx,rdx
      call node.delete
      jc .quit

      ; Print info
      mov rcx,qword txt_code_end
      call printf

      call sysmemcheck
.quit:
      ; Clear stack n quit
      lea rsp,[rsp+(8*31)]
      pop r13
      pop r12
      pop rbx
      pop rbp
      ret

Commentary output (commentary_output.txt):
Code: [Select]

[code begin]


; Create basic list A.
; Print list A.

[nodelist address: 4107856, type: 16777216, first: 4770624, last: 4771200, count: 10]
          [nodedata address: 4770624, type: 16777215, data: 20]
          [nodedata address: 4770688, type: 16777215, data: 21]
          [nodedata address: 4770752, type: 16777215, data: 22]
          [nodedata address: 4770816, type: 16777215, data: 23]
          [nodedata address: 4770880, type: 16777215, data: 24]
          [nodedata address: 4770944, type: 16777215, data: 25]
          [nodedata address: 4771008, type: 16777215, data: 26]
          [nodedata address: 4771072, type: 16777215, data: 27]
          [nodedata address: 4771136, type: 16777215, data: 28]
          [nodedata address: 4771200, type: 16777215, data: 29]
[/nodelist]

; Query nodes from list A.
; Query for nodedata nodes, that (nodedata.data % 3)==0

[query node that (nodedata.data % 3)==0 ] node address 4770688 [/query node]
[query node that (nodedata.data % 3)==0 ] node address 4770880 [/query node]
[query node that (nodedata.data % 3)==0 ] node address 4771072 [/query node]

; Delete, list A., first node
; Delete, list A., last node
; Delete, list A., first->next->next node
; Delete, list A., last->prev->prev node
; Print list A.

[nodelist address: 4107856, type: 16777216, first: 4770688, last: 4771136, count: 6]
          [nodedata address: 4770688, type: 16777215, data: 21]
          [nodedata address: 4770752, type: 16777215, data: 22]
          [nodedata address: 4770880, type: 16777215, data: 24]
          [nodedata address: 4770944, type: 16777215, data: 25]
          [nodedata address: 4771072, type: 16777215, data: 27]
          [nodedata address: 4771136, type: 16777215, data: 28]
[/nodelist]

; Create basic list B.
; Add list B. to list A.
; Create empty list C.
; Add list C. to list B.
; Print list A.

[nodelist address: 4107856, type: 16777216, first: 4770688, last: 4107936, count: 7]
          [nodedata address: 4770688, type: 16777215, data: 21]
          [nodedata address: 4770752, type: 16777215, data: 22]
          [nodedata address: 4770880, type: 16777215, data: 24]
          [nodedata address: 4770944, type: 16777215, data: 25]
          [nodedata address: 4771072, type: 16777215, data: 27]
          [nodedata address: 4771136, type: 16777215, data: 28]
          [nodelist address: 4107936, type: 16777216, first: 4771008, last: 4108016, count: 16]
                    [nodedata address: 4771008, type: 16777215, data: 400]
                    [nodedata address: 4770816, type: 16777215, data: 401]
                    [nodedata address: 4771200, type: 16777215, data: 402]
                    [nodedata address: 4770624, type: 16777215, data: 403]
                    [nodedata address: 4771264, type: 16777215, data: 404]
                    [nodedata address: 4771328, type: 16777215, data: 405]
                    [nodedata address: 4771392, type: 16777215, data: 406]
                    [nodedata address: 4771456, type: 16777215, data: 407]
                    [nodedata address: 4771520, type: 16777215, data: 408]
                    [nodedata address: 4771584, type: 16777215, data: 409]
                    [nodedata address: 4771648, type: 16777215, data: 410]
                    [nodedata address: 4771712, type: 16777215, data: 411]
                    [nodedata address: 4771776, type: 16777215, data: 412]
                    [nodedata address: 4771840, type: 16777215, data: 413]
                    [nodedata address: 4771904, type: 16777215, data: 414]
                    [nodelist address: 4108016, type: 16777216, first: 0, last: 0, count: 0]
                    [/nodelist]
          [/nodelist]
[/nodelist]

; Delete list A.

[node being deleted] node address 4107856 [/node being deleted]
[node being deleted] node address 4770688 [/node being deleted]
[node being deleted] node address 4770752 [/node being deleted]
[node being deleted] node address 4770880 [/node being deleted]
[node being deleted] node address 4770944 [/node being deleted]
[node being deleted] node address 4771072 [/node being deleted]
[node being deleted] node address 4771136 [/node being deleted]
[node being deleted] node address 4107936 [/node being deleted]
[node being deleted] node address 4771008 [/node being deleted]
[node being deleted] node address 4770816 [/node being deleted]
[node being deleted] node address 4771200 [/node being deleted]
[node being deleted] node address 4770624 [/node being deleted]
[node being deleted] node address 4771264 [/node being deleted]
[node being deleted] node address 4771328 [/node being deleted]
[node being deleted] node address 4771392 [/node being deleted]
[node being deleted] node address 4771456 [/node being deleted]
[node being deleted] node address 4771520 [/node being deleted]
[node being deleted] node address 4771584 [/node being deleted]
[node being deleted] node address 4771648 [/node being deleted]
[node being deleted] node address 4771712 [/node being deleted]
[node being deleted] node address 4771776 [/node being deleted]
[node being deleted] node address 4771840 [/node being deleted]
[node being deleted] node address 4771904 [/node being deleted]
[node being deleted] node address 4108016 [/node being deleted]

[code end]

Process completed, Exit Code 0.
Execution time: 00:00.203

; Exit code 0 means, that all items were deleted - memory check -> ok!

Attachment:
Added attachment, named: "nasm_linkedlist_dds_sys_13dec2013.zip", contains PsPad project files, build and compile scripts, source code, description files.



Bye, Encryptor256.
Encryptor256's Investigation \ Research Department.

Offline encryptor256

  • Full Member
  • **
  • Posts: 250
  • Country: lv
  • Win64 .
    • On Youtube: encryptor256
Re: Win64 Linked List (NODELIST) NASM, GOLINK
« Reply #4 on: December 14, 2013, 07:05:06 PM »
Hello!

This is demo, my current, test version.

How to parse bencoded string, torrent file, using node list dds library.

I downloaded ubuntu torrent file and here is parse result:

Code: [Select]

[code begin]


[nodelist address: 4107856, type: 16777216, first: 4815312, last: 4815312, count: 1]
          <dictionary>
                    <string> len: 8, announce </stream>
                    <string> len: 39, http://torrent.ubuntu.com:6969/announce </stream>
                    <string> len: 13, announce-list </stream>
                    <list>
                              <list>
                                        <string> len: 39, http://torrent.ubuntu.com:6969/announce </stream>
                              <list>
                              <list>
                                        <string> len: 44, http://ipv6.torrent.ubuntu.com:6969/announce </stream>
                              <list>
                    <list>
                    <string> len: 7, comment </stream>
                    <string> len: 29, Ubuntu CD releases.ubuntu.com </stream>
                    <string> len: 13, creation date </stream>
                    <integer> 1382003607 </integer>
                    <string> len: 4, info </stream>
                    <dictionary>
                              <string> len: 6, length </stream>
                              <integer> 925892608 </integer>
                              <string> len: 4, name </stream>
                              <string> len: 30, ubuntu-13.10-desktop-amd64.iso </stream>
                              <string> len: 12, piece length </stream>
                              <integer> 524288 </integer>
                              <string> len: 6, pieces </stream>
                              <string> len: 35320, ... </stream>
                    <dictionary>
          <dictionary>
[/nodelist]

[code end]

Process completed, Exit Code 0.
Execution time: 00:00.125


Data structures:

Code: [Select]
      ; Bencoded node types
      node_type_bstream equ (node_type_data-100)
      node_type_binteger equ (node_type_data-101)
      node_type_blist equ (node_type_list+100)
      node_type_bdictionary equ (node_type_list+101)

      ; Bencoded stream node inherits node
      bstreamnode.address equ (8*4)
      bstreamnode.len equ (8*5)
      bstreamnode_size equ (8*6)

      ; Bencoded integer node inherits node
      bintegernode.number equ (8*4)
      bintegernode_size equ (8*5)

      ; Bencoded list node inherits node list
      ; Bencoded dictionary node inherits node list
      bldnode.address equ (8*7)
      bldnode.len equ (8*8)
      bldnode_size equ (8*9)

All this code goes into new library named: btc.

+ fixed minor glitch in dds library, procedure node.add:

Code: [Select]

; there was something like this:

pop rbp

lea rsp,[rsp+8*4]

; but should be like this:

lea rsp,[rsp+8*4]

pop rbp


Added attachment: pspad project files, build scripts, source, description, test files.



Bye, Encryptor256.
Encryptor256's Investigation \ Research Department.