程序集中的链接列表实现

时间:2014-07-05 16:21:16

标签: algorithm assembly data-structures

这是我的链表实现: 节点:

 node struc
    prev dw 0
    next dw 0
    data dw 0
 node ends

此函数添加新节点:

tail - 指向链接列表尾部的指针

_data - 我们要追加的数据

node_add proc near c tail:word, _data_:word

mov bx,tail
mov ax,[bx]

.if ax==0 ;if there's no any nodes yet
;memory allocation; first param - count of blocks to be allocated second param would be segment address of blocks to be allocated
invoke mem_alloc,1,bx 
push ds
mov ds,ax ;ds now contains segment address 
mov ax, _data_ ;store data
mov [ds:node.data],ax
pop ds
.else ;if tail != 0, there's at least one node,we consider there was no error while memory allocation
push ds
mov ds,ax
invoke mem_alloc,1,node.next

push ds
mov ds,ax
mov ax,_data_
mov [ds:node.data],ax
;now we need to store list's tail to new list's tail previous node  
pop ax
mov  [ds:node.prev],ax
;now we need to update list's tail. We consider it's located in @data
mov ax,ds
pop ds
mov bx,tail
mov [bx],ax
.endif
ret

node_add endp

此函数删除节点:

_node - 要删除的节点

__ node - 偏向列表的尾部

__ node_seg - 列表尾部的段地址

mem_free - 释放内存,参数 - 要解除分配的块的地址

remove_node proc near c _node:WORD,__node:WORD,__node_seg:WORD

mov ax,_node

.if ax==0 ;if there's no any nodes
    jmp exit
.endif

push ds

mov ds,_node

.if [ds:node.next]==0 ; if current node doesn't have next node

    .if [ds:node.prev]==0 ; if current node doesn't have previous node

        ;so we have a single node, just remove it

        invoke mem_free,_node
        mov ax,__node_seg ;set node's tail to zero
        mov ds,ax
        mov [ds:__node],0

    .else

        ;so we have have a standard sutiation when there's several nodes

        push [ds:node.prev] ;go to previous node
        pop ds

        xor ax,ax   ;we're about removing, so there's no next node anymore
        mov [ds:node.next],ax


        invoke mem_free,_node
        ;now update list's tail
        push ds
        mov ax,__node_seg
        mov ds,ax
        pop ax

        mov bx,__node
        mov [bx],ax

    .endif

.else

    .if [ds:node.prev]==0 

        ;so node to be deleted is first node

        push [ds:node.next];go to next node
        pop ds

        xor ax,ax ;;we're about removing, so there's no previous node anymore
        mov [ds:node.prev],ax

        invoke mem_free,_node

    .else
        ;yet another situation, node to be deleted is located between two another ones 

        mov cx,[ds:node.next] 
        mov dx,[ds:node.prev]

        mov ds,dx
        mov [ds:node.next],cx
        mov ds,cx
        mov [ds:node.prev],dx

        invoke mem_free,_node

    .endif
.endif


exit:
pop ds

Ret
remove_node endp

现在假设我们从尾部

开始遍历所有节点
push ds
mov cx,node_count ;located in @data
mov ax,node_tail
mov ds,ax

.while cx>0

.if (SOME_CONDITION)

(some actions)

;we're about node removing, and we need to set ds to previous node
mov ax,[ds:node.prev]
push ax
mov bx,@data
push cx
invoke remove_node,ds,offset tail,bx
pop cx
pop bx
mov ax,@data
mov ds,ax

dec node_count

mov ds,bx
jmp __label
.endif

(some actions)

;otherwise just go to next node

mov ax,[ds:node.prev]
mov ds,ax

__label:

dec cx
.endw

问题在于有时某个节点具有相同的node.prev和node.next,有时一个节点可以指向自身!

此代码适用于MS-DOS。

0 个答案:

没有答案