2022-01-07汇编学习00
请注意,本文编写于 326 天前,最后修改于 328 天前,其中某些信息可能已经过时。

List.inc

.586
.model flat,stdcall
option casemap:none
include windows.inc
include user32.inc
include kernel32.inc
include msvcrt.inc


includelib msvcrt.lib
includelib user32.lib
includelib kernel32.lib

Node struct
    m_pNext dd 0 ; 前驱
    m_pPre dd 0  ; 后继
    m_pVal dd 0  ; 数据指针
Node ends

Lst struct
    m_pSentryNode dd 0  ; 哨兵结点
    m_nLen dd 0         ; 长度
Lst ends

; 初始化
InitLst proto :ptr Lst

; 增加表结点
InsertLst proto  :ptr Lst, :LPVOID

; 按索引删除表结点
DeleteLst proto :ptr Lst, :DWORD

; 表是否为空
IsLstEmpty proto  :ptr Lst

; 获取表尾指针
GetLstTail proto  :ptr Lst

; 获取表结点个数
GetLstSize proto  :ptr Lst

; 获取指定索引结点的数据指针
GetLstAt proto  :ptr Lst, :DWORD

; 清空链表
ClearLst proto  : ptr Lst

;删除指定节点
EraseLst proto :ptr Lst, :LPVOID

List.asm

asm
include List.inc


.code

; 初始化
InitLst proc  uses edx esi edi pLst:ptr Lst
    ;清空内存
    invoke RtlZeroMemory, pLst, sizeof Lst
    
    ;申请哨兵节点
    mov esi, pLst
    assume esi: ptr Lst
    
    invoke crt_malloc, sizeof Node
    mov [esi].m_pSentryNode, eax
    .if eax == NULL
        mov eax, FALSE
        ret
    .endif

    mov eax, [esi].m_pSentryNode
    ;长度赋0
    mov [esi].m_nLen, 0
    
    ;非空则指向哨兵
    mov esi, [esi].m_pSentryNode
    assume esi:ptr Node
    mov [esi].m_pNext, eax
    mov [esi].m_pPre, eax
    mov [esi].m_pVal, NULL
    assume esi:nothing
    
    mov eax, TRUE
    ret
InitLst endp

; 增加表结点
InsertLst proc  uses edx esi edi pLst:ptr Lst, pVal:LPVOID
    LOCAL @pNewNode:ptr Node
    LOCAL @pTailNode:ptr Node

    ;申请新结点
;    PNODE pNewNode = (PNODE)malloc(sizeof(NODE));
;    if (pNewNode == NULL)
;    {
;        return NULL;
;    }
    
    invoke crt_malloc, sizeof Node
    mov @pNewNode, eax
    .if @pNewNode == NULL
        mov eax, NULL
        ret
    .endif



    ;获取尾结点
    ;PNODE pTailNode = GetLstTail(pLst);
    invoke GetLstTail, pLst
    mov @pTailNode, eax

    ;新结点赋值
    ;pNewNode->m_pVal = pVal;
    mov esi, @pNewNode
    assume esi: ptr Node
    mov eax, pVal
    mov [esi].m_pVal, eax
    assume esi:nothing

    ;新结点指向头哨兵,头哨兵指向新结点
;    pNewNode->m_pNext = pLst->m_pSentryNode;
;    pLst->m_pSentryNode->m_pPre = pNewNode;
    
    mov esi, @pNewNode
    assume esi: ptr Node
    mov edi, pLst
    assume edi: ptr Lst
    mov eax, [edi].m_pSentryNode
    mov [esi].m_pNext, eax
    
    mov edi, [edi].m_pSentryNode
    assume edi: ptr Node
    mov eax, @pNewNode
    mov [edi].m_pPre, eax
    assume esi:nothing
    assume edi:nothing

    ;尾结点指向新结点,新结点指向尾结点
    ;pTailNode->m_pNext = pNewNode;
    ;pNewNode->m_pPre = pTailNode;
    
    mov eax, @pNewNode
    mov esi, @pTailNode
    assume esi: ptr Node
    mov [esi].m_pNext, eax
    
    mov eax, @pTailNode
    mov edi, @pNewNode
    assume edi: ptr Node
    mov [edi].m_pPre, eax
    assume esi:nothing
    assume edi:nothing
    
    mov esi, pLst
    assume esi: ptr Lst
    inc [esi].m_nLen
    assume esi:nothing
    
    mov eax, @pNewNode
    ret
InsertLst endp

; 按索引删除表结点
DeleteLst proc  uses edx esi edi  pLst:ptr Lst, dwIndex:DWORD
    LOCAL @dwLstSize:DWORD
    LOCAL @pPreNode:ptr Node
    LOCAL @pNode:ptr Node
    
    xor eax, eax
    mov @dwLstSize, eax
    
    invoke GetLstSize, pLst
    .if dwIndex >= eax
        mov eax, FALSE
        ret
    .endif
    
    mov @pPreNode, NULL
    mov esi, pLst 
    assume esi: ptr Lst
    mov eax, [esi].m_pSentryNode
    mov @pNode, eax
    assume esi:nothing
    
    xor ecx, ecx
    .while TRUE
        .if ecx > dwIndex
            .break
        .endif
  
        mov eax, @pNode
        mov @pPreNode, eax
        mov esi, @pNode
        assume esi: ptr Node
        mov eax, [esi].m_pNext
        mov @pNode, eax
        assume esi:nothing
        
        .if ecx == dwIndex
            mov esi, @pPreNode
            assume esi: ptr Node
            mov edi, @pNode
            assume edi: ptr Node 
            mov eax, [edi].m_pNext
            mov [esi].m_pNext, eax
            mov edi, [edi].m_pNext
            mov eax, @pPreNode
            mov [edi].m_pPre, eax
            assume esi:nothing
            assume edi:nothing
            
            mov esi, pLst 
            assume esi: ptr Lst
            dec [esi].m_nLen
            
            invoke crt_free, @pNode
            mov eax, TRUE
            ret
        .endif
        inc ecx
    .endw
    mov eax, FALSE
    ret
DeleteLst endp

; 表是否为空
IsLstEmpty proc  uses esi pLst:ptr Lst
    mov esi, pLst
    assume esi: ptr Lst
    
    .if [esi].m_nLen == 0
        mov eax, TRUE
        ret
    .endif
    mov eax, FALSE
    ret
IsLstEmpty endp

; 获取表尾指针
GetLstTail proc  pLst:ptr Lst
    mov esi, pLst
    assume esi: ptr Lst
    mov eax, [esi].m_pSentryNode
    assume eax: ptr Node
    mov eax, [eax].m_pPre
    ret
GetLstTail endp

; 获取表结点个数
GetLstSize proc  pLst:ptr Lst
    mov eax, pLst
    assume eax: ptr Lst
    mov eax, [eax].m_nLen
    ret
GetLstSize endp

; 获取指定索引结点的数据指针
GetLstAt proc  pLst:ptr Lst, dwIndex:DWORD
    LOCAL @dwLstSize:DWORD
    LOCAL @pPreNode:ptr Node
    LOCAL @pNode:ptr Node
    
    xor eax, eax
    mov @dwLstSize, eax
    
    invoke GetLstSize, pLst
    .if dwIndex >= eax
        mov eax, NULL
        ret
    .endif

    mov esi, pLst
    assume esi: ptr Lst
    mov eax, [esi].m_pSentryNode
    mov @pNode, eax
    assume esi:nothing
    
    xor ecx, ecx
    .while TRUE
        .if ecx > dwIndex
            .break
        .endif
        
        mov esi, @pNode
        assume esi: ptr Node
        mov eax, [esi].m_pNext
        mov @pNode, eax
        assume esi:nothing
        .if ecx == dwIndex
            mov esi, @pNode
            assume esi: ptr Node
            mov eax, [esi].m_pVal
            ret
        .endif
        inc ecx
    .endw
    
    mov eax, NULL
    ret
GetLstAt endp

; 清空链表
ClearLst proc  pLst:ptr Lst
    .while TRUE
        invoke IsLstEmpty, pLst
        .if eax == TRUE
            .break
        .endif
        invoke DeleteLst, pLst, 0
    .endw
    mov eax, TRUE
    ret
ClearLst endp

;删除指定节点
EraseLst proc  pLst:ptr Lst, pVal:LPVOID
    LOCAL @dwLstSize:DWORD
    LOCAL @pPreNode:ptr Node
    LOCAL @pNode:ptr Node
    LOCAL @dwLen:DWORD
    
    xor eax, eax
    mov @dwLstSize, eax
    mov @dwLen, eax
    
    mov @pPreNode, NULL
    mov esi, pLst 
    assume esi: ptr Lst
    mov eax, [esi].m_pSentryNode
    mov @pNode, eax
    mov eax, [esi].m_nLen
    mov @dwLen, eax
    assume esi:nothing
    
    xor ecx, ecx
    .while TRUE
        .if ecx > @dwLen
            .break
        .endif
  
        mov eax, @pNode
        mov @pPreNode, eax
        mov esi, @pNode
        assume esi: ptr Node
        mov eax, [esi].m_pNext
        mov @pNode, eax
        mov eax, @pNode
        assume eax: ptr Node
        mov eax, [eax].m_pVal
        .if eax == pVal
            assume eax:nothing
            assume esi:nothing
            mov esi, @pPreNode
            assume esi: ptr Node
            mov edi, @pNode
            assume edi: ptr Node 
            mov eax, [edi].m_pNext
            mov [esi].m_pNext, eax
            mov edi, [edi].m_pNext
            mov eax, @pPreNode
            mov [edi].m_pPre, eax
            assume esi:nothing
            assume edi:nothing
            
            mov esi, pLst 
            assume esi: ptr Lst
            dec [esi].m_nLen
            
            invoke crt_free, @pNode
            mov eax, TRUE
            ret
        .endif
        inc ecx
    .endw
    mov eax, FALSE
    ret
EraseLst endp
end

本文作者:Na1r

本文链接:

版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!