📄 twowaymergesort.asm
字号:
;-----------------------------------------------------------------------
;-- Move the indices of the buffer and the one of the merged subset.
add edi, 4
add eax, 4
;-----------------------------------------------------------------------
;-- If not all elements have been copied copy the next one.
cmp eax, ebx
jb @B
@Return:
ret
TwoWayMergeSort_Merge ENDP
ELSE
TwoWayMergeSort_PURE PROTO :DWORD, :DWORD
NaturalTwoWayMergeSort_PURE PROTO :DWORD, :DWORD
StraightTwoWayMergeSort_PURE PROTO :DWORD, :DWORD
TwoWayMergeSort_Sort_PURE PROTO :DWORD, :DWORD
TwoWayMergeSort_Merge_PURE PROTO :DWORD, :DWORD, :DWORD
TwoWayMergeSort_PURE PROC Arr:DWORD, count:DWORD
mov eax, Arr
mov TWMS_Arr, eax
mov eax, count
shl eax, 2
mov SortInfo.usedMemory, eax
invoke SysAllocStringByteLen, 0, eax
test eax, eax
jz @InsufficientMemory
mov SortInfo.hMemory, eax
mov eax, count
dec eax
push eax
push 0
call TwoWayMergeSort_Sort_PURE
invoke SysFreeString, SortInfo.hMemory
@Return:
ret
@InsufficientMemory:
mov SortInfo.errorId, ERROR_NOT_ENOUGH_MEMORY
ret
TwoWayMergeSort_PURE ENDP
NaturalTwoWayMergeSort_PURE PROC Arr:DWORD, count:DWORD
mov eax, Arr
mov TWMS_Arr, eax
mov eax, count
shl eax, 2
mov SortInfo.usedMemory, eax
invoke SysAllocStringByteLen, 0, eax
test eax, eax
jz @InsufficientMemory
mov SortInfo.hMemory, eax
mov esi, TWMS_Arr
mov edi, count
lea edi, [esi + edi*4 - 4]
@Loop1:
mov eax, esi
sub eax, 4
@Loop2:
mov ebx, eax
add ebx, 4
mov ecx, ebx
@Loop3:
cmp ecx, edi
jnb @Loop2a
;-------------------------------------------------------------------------------
IncCMPCounter
;-------------------------------------------------------------------------------
mov edx, DWORD PTR [ecx]
add ecx, 4
cmp DWORD PTR [ecx], edx
jae @Loop3
sub ecx, 4
@Loop2a:
mov eax, ecx
cmp ecx, edi
jnb @Loop2Foot
add eax, 4
@Loop4:
cmp eax, edi
jnb @Loop2b
;-------------------------------------------------------------------------------
IncCMPCounter
;-------------------------------------------------------------------------------
mov edx, DWORD PTR [eax]
add eax, 4
cmp DWORD PTR [eax], edx
jae @Loop4
sub eax, 4
@Loop2b:
push ebx
push esi
push eax
push edi
sub ebx, esi
sub ecx, esi
sub eax, esi
shr ebx, 2
shr ecx, 2
shr eax, 2
push eax
push ecx
push ebx
call TwoWayMergeSort_Merge_PURE
pop edi
pop eax
pop esi
pop ebx
@Loop2Foot:
cmp eax, edi
jb @Loop2
cmp ebx, esi
jne @Loop1
invoke SysFreeString, SortInfo.hMemory
@Return:
ret
@InsufficientMemory:
mov SortInfo.errorId, ERROR_NOT_ENOUGH_MEMORY
ret
NaturalTwoWayMergeSort_PURE ENDP
StraightTwoWayMergeSort_PURE PROC Arr:DWORD, count:DWORD
mov eax, Arr
mov TWMS_Arr, eax
mov eax, count
shl eax, 2
mov SortInfo.usedMemory, eax
invoke SysAllocStringByteLen, 0, eax
test eax, eax
jz @InsufficientMemory
mov SortInfo.hMemory, eax
mov esi, count
dec esi
mov eax, 1
@Loop1:
mov edx, -1
@Loop2:
mov ecx, edx
add ecx, eax
cmp ecx, esi
jnb @Loop1a
mov edi, edx
inc edi
mov ebx, edx
add ebx, eax
mov edx, ebx
add edx, eax
cmp edx, esi
jbe @Merge
mov edx, esi
@Merge:
push eax
push edx
push esi
push edx
push ebx
push edi
call TwoWayMergeSort_Merge_PURE
pop esi
pop edx
pop eax
jmp @Loop2
@Loop1a:
shl eax, 1
cmp eax, esi
jbe @Loop1
invoke SysFreeString, SortInfo.hMemory
@Return:
ret
@InsufficientMemory:
mov SortInfo.errorId, ERROR_NOT_ENOUGH_MEMORY
ret
StraightTwoWayMergeSort_PURE ENDP
TwoWayMergeSort_Sort_PURE PROC left:DWORD, right:DWORD
mov ebx, left
mov ecx, right
cmp ebx, ecx
je @Return
mov eax, ebx
add eax, ecx
shr eax, 1
push eax
push ebx
push ecx
push eax
push ebx
call TwoWayMergeSort_Sort_PURE ; sort from left to middle
pop ecx
pop ebx
pop eax
push eax
push ebx
push ecx
push ecx
inc eax
push eax
call TwoWayMergeSort_Sort_PURE ; sort from middle + 1 to right
pop ecx
pop ebx
pop eax
push ecx ; index of the right element
push eax ; index of the medially element
push ebx ; index of the left element
call TwoWayMergeSort_Merge_PURE ; merge
@Return:
ret
TwoWayMergeSort_Sort_PURE ENDP
TwoWayMergeSort_Merge_PURE PROC left:DWORD, mid:DWORD, right:DWORD
mov edi, SortInfo.hMemory ; EDI = offset of a buffer
mov edx, TWMS_Arr ; EDX = offset of the subset that shall be merged
mov eax, left
lea eax, [edx + eax*4] ; EAX = offset of the left subset
mov ecx, mid
lea ecx, [edx + ecx*4] ; ECX = end of the left subset
lea ebx, [ecx + 4] ; EBX = offset of the right subset
mov esi, right
lea esi, [edx + esi*4] ; ESI = end of the right subset
;---------------------------------------------------------------------------
;-- If either the left or the right subset is processed abort the loop.
@Loop1:
cmp eax, ecx
ja @CopyTemp
cmp ebx, esi
ja @Copy1stSequence
;-------------------------------------------------------------------------------
IncCMPCounter
;-------------------------------------------------------------------------------
;-------------------------------------------------------------------------
;-- Is the element from the left subset greater thab the one from the
;-- right?
mov edx, DWORD PTR [eax]
cmp edx, DWORD PTR [ebx]
ja @CopyFrom2nd
;-----------------------------------------------------------------------
;-- No. Copy the element from the left subset to the buffer.
mov DWORD PTR [edi], edx
;-------------------------------------------------------------------------------
IncMOVCounter
;-------------------------------------------------------------------------------
;-----------------------------------------------------------------------
;-- Increment the indices of the left subset and of the buffer.
add eax, 4
add edi, 4
jmp @Loop1
;-----------------------------------------------------------------------
;-- Yes. Copy the element from the right subset to the buffer.
@CopyFrom2nd:
mov edx, DWORD PTR [ebx]
mov DWORD PTR [edi], edx
;-------------------------------------------------------------------------------
IncMOVCounter
;-------------------------------------------------------------------------------
;-------------------------------------------------------------------------
;-- Increment the indices of the right subset and of the buffer.
add ebx, 4
add edi, 4
jmp @Loop1
;---------------------------------------------------------------------------
;-- The right subset is completely processed. Now copy the remaining (not
;-- processed) elements of the left subset to the buffer.
@Copy1stSequence:
;-------------------------------------------------------------------------
;-- Move the index of the right subset to the last element.
sub ebx, 4
;-------------------------------------------------------------------------
;-- Load the next element from the left subset and copy it to the right
;-- subset.
mov edx, DWORD PTR [ecx]
mov DWORD PTR [ebx], edx
;-------------------------------------------------------------------------------
IncMOVCounter
;-------------------------------------------------------------------------------
;---------------------------------------------------------------------------
;-- Move the index of the left subset to the previos element.
sub ecx, 4
;-------------------------------------------------------------------------
;-- If not all remaining elements have been copyied copy the next one.
cmp ecx, eax
jae @Copy1stSequence
;---------------------------------------------------------------------------
;-- The left subset is completely processed. Now copy the buffer to the
;-- source.
@CopyTemp:
mov edi, SortInfo.hMemory ; EDI = offset of the buffer
mov eax, left
shl eax, 2
add eax, TWMS_Arr ; EAX = offset of the merged subset
@@:
;-----------------------------------------------------------------------
;-- Copy the element of the buffer to the merged subset.
mov edx, DWORD PTR [edi]
mov DWORD PTR [eax], edx
;-------------------------------------------------------------------------------
IncMOVCounter
;-------------------------------------------------------------------------------
;-----------------------------------------------------------------------
;-- Move the indices of the buffer and the one of the merged subset.
add edi, 4
add eax, 4
;-----------------------------------------------------------------------
;-- If not all elements have been copied copy the next one.
cmp eax, ebx
jb @B
@Return:
ret
TwoWayMergeSort_Merge_PURE ENDP
ENDIF
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -