⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ciosort.asm

📁 用汇编的类编程实现快速排序的例子
💻 ASM
字号:
ifndef _QUEUE_
    ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
    ;EQU 设置
    ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
    _QUEUE_           EQU   1
    MAX_POINTER       EQU   1024
    SIGN_GREATEST     EQU   1
    SIGN_EQUAL        EQU   2
    SIGN_LESS         EQU   3
   
    ; --=====================================================================================--
    CLS_QUEUE_Init        PROTO :DWORD,:DWORD
    QUEUE_Destructor      PROTO :DWORD 
    QUEUE_QueryClient     PROTO :DWORD,:DWORD,:DWORD
    QUEUE_InsertClient    PROTO :DWORD,:DWORD,:DWORD
    QUEUE_DeleteClient    PROTO :DWORD,:DWORD
    QUEUE_BackMove        PROTO :DWORD,:DWORD
    QUEUE_PriorMove       PROTO :DWORD,:DWORD
    QUEUE_GetClient       PROTO :DWORD,:DWORD 
    QUEUE_OutputFile      PROTO :DWORD,:DWORD

    CLS_QUEUE_InitPto     TYPEDEF PROTO :DWORD,:DWORD
    QUEUE_DestructorPto   TYPEDEF PROTO :DWORD 
    QUEUE_QueryClientPto  TYPEDEF PROTO :DWORD,:DWORD,:DWORD
    QUEUE_InsertClientPto TYPEDEF PROTO :DWORD,:DWORD,:DWORD
    QUEUE_DeleteClientPto TYPEDEF PROTO :DWORD,:DWORD
    QUEUE_GetClientPto    TYPEDEF PROTO :DWORD,:DWORD 
    QUEUE_OutputFilePto   TYPEDEF PROTO :DWORD,:DWORD

    ; --=====================================================================================--
    CLASS CLS_QUEUE,QUEUE
       ;类方法定义
       CMETHOD Destructor               ;类清理程序
       CMETHOD QueryClient              ;查找客户端信息
       CMETHOD InsertClient             ;增加客户端信息
       CMETHOD DeleteClient             ;删除客户端信息
       CMETHOD OutputFile               ;将结果输出到文件
       ;类成员变量定义
       m_Count          dd      ?       ;数组内记录数
       m_lpQueue        dd      ?       ;指针数组
    CLS_QUEUE ENDS
    
    .data
    
       ;类初始化
       BEGIN_INIT 
          ;函数指针初始化(指定调用那个函数)
          dd offset QUEUE_Destructor  
          dd offset QUEUE_QueryClient
          dd offset QUEUE_InsertClient
          dd offset QUEUE_DeleteClient
          dd offset QUEUE_OutputFile
          ;成员变量初始化
          dd 0,0
       END_INIT 
             
    .code    
    
    CLS_QUEUE_Init PROC uses edi esi lpTHIS:DWORD,_lpResult:DWORD
       ;说明当前类名为【CLS_QUEUE】
       SET_CLASS CLS_QUEUE
       ;指定EDI为类指针
       SetObject edi,CLS_QUEUE
       
       mov    esi,_lpResult
       mov    dword ptr [esi],TRUE
       ;申请错误信息字符串内存
       invoke LocalAlloc,LPTR,MAX_POINTER*sizeof dword
       .if eax==NULL
          mov    dword ptr [esi],FALSE
          jmp    @F
       .endif
       mov    [edi].m_lpQueue,eax
    @@:
       ;取消EDI类指针指定
       ReleaseObject edi
       ret
    CLS_QUEUE_Init ENDP
    
    QUEUE_Destructor PROC uses edi esi ebx lpTHIS:DWORD 
    
       SetObject edi,CLS_QUEUE
       .if [edi].m_lpQueue!=0
          mov    esi,[edi].m_lpQueue
          xor    ebx,ebx
          .while ebx<[edi].m_Count
             mov    eax,[esi]
             .if eax!=0
                 invoke LocalFree,eax
             .endif
             add    esi,sizeof dword
             inc    ebx
          .endw
          invoke LocalFree,[edi].m_lpQueue
       .endif
       ReleaseObject edi
       ret
    QUEUE_Destructor ENDP
    
    QUEUE_QueryClient PROC uses edi esi ebx edx lpTHIS:DWORD,_lpUserGh:DWORD,_lpResult:DWORD
       LOCAL @lpContext     :DWORD
       LOCAL @lpUserGh      :DWORD
       LOCAL @hClient       :DWORD
       LOCAL @dwIndexFirst  :DWORD
       LOCAL @dwIndexCurrent:DWORD
       LOCAL @dwIndexLast   :DWORD
    
       SetObject edi,CLS_QUEUE
       
       mov    @dwIndexFirst  ,0                       ;初始化位置指针
       mov    @dwIndexCurrent,0                       
       m2m    @dwIndexLast   ,[edi].m_Count
       dec    @dwIndexLast
       mov    esi,[edi].m_lpQueue                     ;查找首指针
    @@:
       .if esi==NULL                                  ;〖空〗说明后面没值
          mov    esi,_lpResult
          mov    dword ptr [esi],SIGN_GREATEST
          jmp    @F
       .endif
       
       mov    eax,[esi]                               ;指针指向串地址
       m2m    @hClient ,dword ptr [eax]
       add    eax,sizeof dword
       mov    @lpUserGh,eax
       
       ;invoke lstrcmpi,_lpUserGh,CTEXT("123458")
       ;.if eax==0
       ;   invoke _ShowConnect,CTEXT("First=%d Last=%d"),@dwIndexFirst,@dwIndexLast
       ;   invoke _ShowConnect,CTEXT("Current=%d %c"),@dwIndexCurrent,10
       ;.endif
       invoke lstrcmpi,_lpUserGh,@lpUserGh
       .if eax==-1                                    ;参数工号小于对应的工号,需要向前查找
          mov    eax,@dwIndexCurrent
          .if eax==@dwIndexFirst ;指针越界表示未查找出结果〖〗
             mov    esi,_lpResult
             mov    dword ptr [esi],SIGN_LESS
             jmp    @F
          .else
             ;dec    @dwIndexCurrent                   ;向前移动指针
             m2m    @dwIndexLast,@dwIndexCurrent
             dec    @dwIndexLast
          .endif
         
          mov    eax,@dwIndexCurrent                  ;查找中间值 Current-(Current-First)/2*(Sizeof Dword)
          sub    eax,@dwIndexFirst
          xor    edx,edx
          mov    ebx,2
          div    ebx
          .if edx!=0
             inc    eax
          .endif
          sub    @dwIndexCurrent,eax

          mov    ebx,sizeof dword
          mul    ebx
          sub    esi,eax
          jmp    @B
       .elseif eax>0                                  ;参数工号大于对应的工号,需要向后查找
          mov    eax,@dwIndexCurrent
          .if @dwIndexLast==eax                       ;指针越界表示未查找出结果〖〗
             mov    esi,_lpResult
             mov    dword ptr [esi],SIGN_GREATEST
             jmp    @F
          .else
             ;inc    @dwIndexCurrent                   ;向后移动指针
             m2m    @dwIndexFirst,@dwIndexCurrent
             inc    @dwIndexFirst
          .endif
          mov    eax,@dwIndexLast                     ;查找中间值 Current+(Last-Current)/2*(Sizeof Dword)
          sub    eax,@dwIndexCurrent
          xor    edx,edx
          mov    ebx,2
          div    ebx
          .if edx!=0
             inc    eax
          .endif
          add    @dwIndexCurrent,eax

          mov    ebx,sizeof dword
          mul    ebx
          add    esi,eax
          jmp    @B
       .else                                   ;参数工号等于对应的工号
          mov    esi,_lpResult
          mov    dword ptr [esi],SIGN_EQUAL
          jmp    @F
       .endif
     @@:
       ReleaseObject edi
       mov    eax,@dwIndexCurrent
       ret
    QUEUE_QueryClient ENDP

    QUEUE_InsertClient PROC uses edi esi ebx lpTHIS:DWORD,_lpUserGh:DWORD,_hClient:DWORD
       LOCAL @dwResult :DWORD
       LOCAL @dwIndex  :DWORD
       LOCAL @dwLength :DWORD
       
       SetObject edi,CLS_QUEUE
       .if [edi].m_Count!=0
          invoke QUEUE_QueryClient,lpTHIS,_lpUserGh,addr @dwResult
          mov    @dwIndex,eax
          .if @dwResult==SIGN_GREATEST || @dwResult==SIGN_EQUAL ;大于等于均放到最后
             ;invoke _ShowConnect,CTEXT("UserGh=%s 的位置在%d后"),_lpUserGh,@dwIndex
             
             inc    @dwIndex
             invoke QUEUE_BackMove,lpTHIS,@dwIndex
          .else
             ;invoke _ShowConnect,CTEXT("UserGh=%s 的位置在%d前"),_lpUserGh,@dwIndex
             
             invoke QUEUE_BackMove,lpTHIS,@dwIndex
          .endif
       .else
          mov    @dwIndex,0
          ;invoke _ShowConnect,CTEXT("UserGh=%s 的位置首位置"),_lpUserGh,10
       .endif

       mov    esi,[edi].m_lpQueue                         ;移动存放位置指针
       mov    eax,@dwIndex
       mov    ebx,sizeof dword
       mul    ebx
       add    esi,eax
       
       invoke lstrlen,_lpUserGh                           ;计算申请内存大小
       add    eax,sizeof dword
       inc    eax
       mov    @dwLength,eax
       invoke LocalAlloc,LPTR,@dwLength
       .if eax!=NULL
          mov    [esi],eax                                ;写入申请地址
          mov    esi,eax

          m2m    dword ptr [esi],_hClient
          add    esi,sizeof dword

          invoke lstrcpy,esi,_lpUserGh
          inc    [edi].m_Count
       .else
          invoke _ShowConnect,CTEXT("申请〖%d〗大小的内存%s"),@dwLength,CTEXT("失败")
       .endif

       ReleaseObject edi
       ret
    QUEUE_InsertClient ENDP
    
    QUEUE_DeleteClient PROC uses edi esi ebx lpTHIS:DWORD,_hClient:DWORD
       
       SetObject edi,CLS_QUEUE
       mov    esi,[edi].m_lpQueue        ;设置开始移动指针
       xor    ebx,ebx
       .while ebx<[edi].m_Count
          mov    eax,[esi]
          mov    eax,[eax]
          .if _hClient==eax
              mov    eax,[esi]
              invoke LocalFree,eax
              invoke QUEUE_PriorMove,lpTHIS,ebx
              dec    [edi].m_Count
              .break
          .endif
          add    esi,sizeof dword
          inc    ebx
       .endw

       ReleaseObject edi
       ret
    QUEUE_DeleteClient ENDP

    QUEUE_BackMove PROC uses edi esi ebx edx lpTHIS:DWORD,_dwIndex:DWORD
       
       SetObject edi,CLS_QUEUE
       .if [edi].m_Count<MAX_POINTER
          mov    esi,[edi].m_lpQueue        ;设置开始移动指针
          mov    eax,[edi].m_Count
          dec    eax
          mov    ebx,sizeof dword
          mul    ebx
          add    esi,eax
          mov    ebx,[edi].m_Count
          .while ebx>_dwIndex
             mov    eax,[esi]
             mov    [esi+sizeof dword],eax
             sub    esi,sizeof dword
             dec    ebx
          .endw
       .endif

       ReleaseObject edi
       ret
    QUEUE_BackMove ENDP

    QUEUE_PriorMove PROC uses edi esi ebx edx lpTHIS:DWORD,_dwIndex:DWORD
       
       SetObject edi,CLS_QUEUE
       mov    esi,[edi].m_lpQueue        ;设置开始移动指针

       mov    eax,_dwIndex
       mov    ebx,sizeof dword
       mul    ebx
       add    esi,eax
       mov    ebx,_dwIndex
       .while ebx<[edi].m_Count
          mov    eax,[esi+sizeof dword]
          mov    [esi],eax
          add    esi,sizeof dword
          inc    ebx
       .endw

       ReleaseObject edi
       ret
    QUEUE_PriorMove ENDP

    QUEUE_GetClient PROC uses edi esi ebx lpTHIS:DWORD,_dwIndex:DWORD 
       LOCAL @dwResult:DWORD
    
       SetObject edi,CLS_QUEUE
       mov    @dwResult,0
       mov    esi,[edi].m_lpQueue        ;设置开始移动指针

       mov    eax,_dwIndex
       mov    ebx,sizeof dword
       mul    ebx
       add    esi,eax
       mov    eax,[esi]
       mov    @dwResult,eax

       ReleaseObject edi
       mov    eax,@dwResult
       ret
    QUEUE_GetClient ENDP

    QUEUE_OutputFile PROC uses edi esi ebx lpTHIS:DWORD,_lpWriteFile:DWORD
       LOCAL @hFile:DWORD
       LOCAL @dwLen:DWORD
       LOCAL @szBuffer[1024]:BYTE
       LOCAL @hAccept:DWORD
       LOCAL @lpUserGh:DWORD
       
       SetObject edi,CLS_QUEUE
       invoke CreateFile,_lpWriteFile,GENERIC_WRITE,FILE_SHARE_WRITE,0,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,0
       .if eax!=INVALID_HANDLE_VALUE
          mov    @hFile,eax
          invoke RtlZeroMemory,addr @szBuffer,sizeof @szBuffer
          mov    esi,[edi].m_lpQueue        ;设置开始移动指针
          xor    ebx,ebx
          .while ebx<[edi].m_Count
             mov    eax,[esi]
             m2m    @hAccept,[eax]
             add    eax,sizeof dword
             m2m    @lpUserGh,eax
             invoke wsprintf,addr @szBuffer,CTEXT("hAccept=%d UserGh=%s%c%c"),@hAccept,@lpUserGh,13,10
             invoke lstrlen,addr @szBuffer
             mov    @dwLen,eax
             invoke WriteFile,@hFile,addr @szBuffer,@dwLen,addr @dwLen,NULL
             add    esi,sizeof dword
             inc    ebx
          .endw
          invoke CloseHandle,@hFile
       .endif
         
       ReleaseObject edi
       ret
    QUEUE_OutputFile ENDP
endif

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -