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

📄 sorting.asm

📁 一个演示了用汇编语言编写的数据排序算法,源代码非常详细
💻 ASM
📖 第 1 页 / 共 3 页
字号:

;-----------------------------------------------------------------------------------------
; Prototypes.
;-----------------------------------------------------------------------------------------

  PaintElements      PROTO :DWORD, :DWORD, :DWORD

  StartSorting       PROTO
  CancelSorting      PROTO
  SortingThread      PROTO :DWORD
  InitSortInfoStruct PROTO :DWORD
  StartAlgorithm     PROTO :DWORD


.code

AddErrorString MACRO

  lea    eax, localBuffer
  .IF SortInfo.errorId != ERROR_SUCCESS
      invoke szCopy, OFFSET LVI_Error, ADDR localBuffer
      lea    eax, localBuffer
      add    eax, SIZEOF LVI_Error - 1
  .ENDIF

ENDM


;-----------------------------------------------------------------------------------------
; Display- and delay-macros.
;-----------------------------------------------------------------------------------------

RefreshElement MACRO element:REQ, hDC:=<NULL>

  LOCAL Return

  ;---------------------------------------------------------------------------------------
  ;-- Paint the elements only if the graphic dialog is shown.
  cmp    SortInfo.fGraphic, 0
  jz     Return

  pushad
    invoke PaintElements, element, hDC, FALSE
  popad

Return:
ENDM

IncCMPCounter MACRO

  LOCAL Return

  ;---------------------------------------------------------------------------------------
  ;-- Increment the comparison counter.
  add    DWORD PTR [SortInfo.cmpCounter + 4], 1


  ;---------------------------------------------------------------------------------------
  ;-- Note: JNC + INC is measurable faster (at least on a Pentium IV)
  jnc    Return
  inc    DWORD PTR [SortInfo.cmpCounter]

Return:
ENDM

IncMOVCounter MACRO

  LOCAL Return

  ;---------------------------------------------------------------------------------------
  ;-- Increment the exchange counter.
  add DWORD PTR [SortInfo.movCounter + 4], 1


  ;---------------------------------------------------------------------------------------
  ;-- Note: JNC + INC is measurable faster (at least on a Pentium IV)
  jnc    Return
  inc    DWORD PTR [SortInfo.movCounter]

Return:
ENDM

WaitDelay MACRO

  LOCAL Label1

    ;-------------------------------------------------------------------------------------
    ;-- Get the current tick count.
    invoke GetTickCount
    mov    edx, SortInfo.delay
    sub    eax, edx


    ;-------------------------------------------------------------------------------------
    ;-- Is the selected delay elapsed?
    cmp    eax, SortInfo.lastTickCount
    ja     Label1


    ;-------------------------------------------------------------------------------------
    ;-- No, sleep the rest of the time.
    push   eax
    push   edx

      sub    eax, SortInfo.lastTickCount
      neg    eax

      push   eax
        invoke Sleep, eax
      pop    ebx

    pop    edx
    pop    eax

    add    eax, ebx
    add    eax, edx


  ;---------------------------------------------------------------------------------------
  ;-- Save the current tick count.
  Label1:
    mov    SortInfo.lastTickCount, eax

ENDM

DelayAfterPass MACRO

  LOCAL Return

  ;---------------------------------------------------------------------------------------
  ;-- If no delay is selected return.
  cmp    SortInfo.delay, 0
  jz     Return


  ;---------------------------------------------------------------------------------------
  ;-- If the delay position is not 'after each pass' return.
  cmp    SortInfo.fDelayPosition, DELAY_AFTER_PASS
  jne    Return

  pushad

    ;-------------------------------------------------------------------------------------
    ;-- Ensure that the selected delay is elapsed.
    WaitDelay

  popad

Return:
ENDM

DelayAfterComparison MACRO element1:REQ, element2

  LOCAL Return


  ;---------------------------------------------------------------------------------------
  ;-- If no delay is selected return.
  cmp    SortInfo.delay, 0
  jz     Return


  ;---------------------------------------------------------------------------------------
  ;-- If the delay position is not 'after each comparison' return.
  cmp    SortInfo.fDelayPosition, DELAY_AFTER_COMPARISON
  jne    Return


  pushad

    mov    Element1, element1
    IFDEF element2
       mov    Element2, element2
    ELSE
       mov    Element2, -1
    ENDIF


    ;-------------------------------------------------------------------------------------
    ;-- Paint these elements with a special color.
    invoke PaintElements, Element1, 0, TRUE
    IFDEF element2
       invoke PaintElements, Element2, 0, TRUE
    ENDIF


    ;-------------------------------------------------------------------------------------
    ;-- Ensure that the selected delay is elapsed.
    WaitDelay


    ;-------------------------------------------------------------------------------------
    ;-- Paint these elements with the normal color.
    invoke PaintElements, Element1, 0, FALSE
    mov    Element1, -1
    IFDEF element2
       invoke PaintElements, Element2, 0, FALSE
       mov    Element2, -1
    ENDIF

  popad

Return:
ENDM

DelayAfterExchange MACRO

  LOCAL Return

  ;---------------------------------------------------------------------------------------
  ;-- If no delay is selected return.
  cmp    SortInfo.delay, 0
  jz     Return


  ;---------------------------------------------------------------------------------------
  ;-- If the delay position is not 'after each exchange' return.
  cmp    SortInfo.fDelayPosition, DELAY_AFTER_EXCHANGE
  jne    Return

  pushad

    ;-------------------------------------------------------------------------------------
    ;-- Ensure that the selected delay is elapsed.
    WaitDelay

  popad

Return:
ENDM



;-----------------------------------------------------------------------------------------
; Purpose:     Displays the values of each element of an array (the pointer to this array
;              is SortInfo.lpElements) by drawing lines with different lengths.
;
; Inputs:      element - index of the element that shall be painted; if -1, then all
;                        elements are painted
;              hDC - handle of a display device context (can be NULL)
;              fSpecialColor - if TRUE the element will be painted with a special color
;
; Outputs:     none
;
; Notes:       For displaying the values the display window of the graphic dialog is used.
;-----------------------------------------------------------------------------------------

PaintElements PROC element:DWORD, hDC:DWORD, fSpecialColor:DWORD

  LOCAL hBrushOld   :DWORD
  LOCAL hPenOld     :DWORD
  LOCAL fReleaseDC  :BYTE


  mov    fReleaseDC, FALSE
  .IF (hDC == NULL) || fSpecialColor
@@:
      mov    fReleaseDC, TRUE

      ;-----------------------------------------------------------------------------------
      ;-- Get a handle of a display device context for the display window and save it.
      invoke GetDC, hGraphicDialog_S_Display
      mov    hDC, eax


      ;-----------------------------------------------------------------------------------
      ;-- If the handle is invalid return.
      test   eax, eax
      jz     @Return

  .ENDIF



  .IF element == -1

      ;-----------------------------------------------------------------------------------
      ;-- Paint all elements.
      

      ;-----------------------------------------------------------------------------------
      ;-- Paint the background.
      invoke SelectObject, hDC, hBrush_Background
      mov    hBrushOld, eax
      invoke SelectObject, hDC, hPen_BackgroundFrame
      mov    hPenOld, eax
      invoke Rectangle, hDC, 0, 0, Display_Right, Display_Bottom


      ;-----------------------------------------------------------------------------------
      ;-- Now display the values.
      mov    ebx, Display_Right
      inc    ebx
      shr    ebx, 1

      mov    edx, Display_Bottom
      inc    edx
      shr    edx, 1

      mov    eax, SortInfo.numElements
      .IF fDisplayLines
          ;-------------------------------------------------------------------------------
          ;-- Display lines.
          lea    eax, [eax*2]
          sub    ebx, eax

      .ELSE
          ;-------------------------------------------------------------------------------
          ;-- Display points.
          shl    eax, 1
          sub    ebx, eax
          shr    eax, 2
          add    edx, eax

      .ENDIF


      xor    ecx, ecx

    @Loop1:
        ;---------------------------------------------------------------------------------
        ;-- Get the value of the current element.
        mov    esi, SortInfo.lpElements
        mov    eax, DWORD PTR [esi + ecx*4]


        ;---------------------------------------------------------------------------------
        ;-- Select the proper color for this value.
        push eax
        push ebx
        push ecx
        push edx
          invoke SelectObject, hDC, DWORD PTR [OFFSET hPens_Array + eax*4]
        pop edx
        pop ecx
        pop ebx
        pop eax


        .IF fDisplayLines
            ;-----------------------------------------------------------------------------
            ;-- Display lines.


            ;-----------------------------------------------------------------------------
            ;-- Divide the value by 2.
            shr    eax, 1

            push   eax
            push   ebx
            push   ecx
            push   edx

              ;---------------------------------------------------------------------------
              ;-- Calculate the start coordinates of the line.
              lea    ecx, [ecx*4 + ebx]

              sub    edx, eax


              ;---------------------------------------------------------------------------
              ;-- Move to the calculated position.
              invoke MoveToEx, hDC, ecx, edx, 0

            pop    edx
            pop    ecx
            pop    ebx
            pop    eax

            push   ebx
            push   ecx
            push   edx

              ;---------------------------------------------------------------------------
              ;-- Calculate the end coordinates of the line.
              lea    ecx, [ecx*4 + ebx]

              lea    edx, [edx + eax + 1]


              ;---------------------------------------------------------------------------
              ;-- Draw the line.
              invoke LineTo, hDC, ecx, edx

            pop    edx
            pop    ecx
            pop    ebx

        .ELSE
            ;-----------------------------------------------------------------------------
            ;-- Display points.

            push   eax
            push   ebx
            push   ecx
            push   edx

              ;---------------------------------------------------------------------------
              ;-- Calculate the start coordinates of the line.
              lea    ebx, [ebx + ecx*4]

              sub    edx, eax


              ;---------------------------------------------------------------------------
              ;-- Move to the calculated position and draw the line.
              push   ebx
              push   edx
                invoke MoveToEx, hDC, ebx, edx, 0
              pop    edx
              pop    ebx
              inc    edx
              invoke LineTo, hDC, ebx, edx

            pop    edx
            pop    ecx
            pop    ebx
            pop    eax

        .ENDIF


        ;---------------------------------------------------------------------------------
        ;-- Have all elements been drawn?
        inc    ecx
        cmp    ecx, SortInfo.numElements
        jb     @Loop1


      ;-----------------------------------------------------------------------------------
      ;-- Yes. Restore the old brush.

⌨️ 快捷键说明

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