Mergesort Example
; MSORT (MERGESORT)
INCLUDE IRVINE16.INC
.DATA
ARRAY WORD 13, 24, 32, 56, 47, 63, 44, 35, 26, 73, 32, 53, 28, 77, 23, 42
N = ($-ARRAY)/2
LOWHLFTOP WORD ?
UPPHLFTOP WORD ?
.CODE
MAIN PROC
MOV AX, @DATA
MOV DS, AX
MOV CX, N
MOV SI, OFFSET ARRAY
L1: MOV AX, [SI]
PUSH AX ; PUSH ARRAY OF WORDS ONTO STACK
ADD SI, 2
LOOP L1
MOV SI, SP
MOV BX, N
CALL MSORT ; MERGESORT DATA ON STACK
MOV CX, N
L2: POP AX ; POP WORDS AND DISPLAY THEM
CALL WRITEINT
CALL CRLF
LOOP L2
CALL READINT ; CHEAP FIX
MOV AX, 4CH
INT 21H
MAIN ENDP
MSORT PROC
; RECEIVES
; SI = POINTER INTO STACK WHERE LIST BEGINS
; BX = # WORDS IN LIST
; RETURNS WITH LIST SORTED (AND REGISTERS SCRAMBLED)
CMP BX, 1
JG L1
RET
L1: MOV BP, SI
MOV CX, BX
L2: MOV AX, [BP] ; COPY ORIGINAL LIST ONTO STACK AGAIN
PUSH AX
ADD BP, 2
LOOP L2
MOV AX, SP
PUSH SI ; SAVE SI AND BX FOR AFTER NEXT MSORT CALL
PUSH BX
MOV SI, AX ; SI = BASE OF LOWER 1/2 LIST
SHR BX, 1 ; BX = # WORDS IN 1/2 LIST
CALL MSORT ; NOW SORT LOWER 1/2 LIST
POP BX ; RESTORE SI AND BX
POP SI
MOV AX, SP
ADD AX, BX ; BX = # WORDS IN LIST = # BYTES IN 1/2 LIST
PUSH SI ; AGAIN SAVE SI AND BX FOR AFTER NEXT MSORT CALL
PUSH BX
MOV SI, AX ; SI = BASE OF UPPER 1/2 LIST
SHR BX, 1 ; BX = # WORDS IN 1/2 LIST
CALL MSORT ; NOW SORT UPPER 1/2 LIST
POP BX ; RESTORE SI AND BX
POP SI
; BOTH HALVES ARE NOW SORTED, SO NOW MERGE THEM. BUT THERE'S A TECHNICAL PROBLEM:
; ONLY SP AND BP CAN BE USED TO INDIRECTLY ACCESS THE STACK, SO WATCH....
MOV CX, BX ; PREP COUNTER FOR MERGING LOOP
MOV DX, SP ; DX WILL HOLD POINTER INTO LOWER 1/2 LIST
MOV DI, SP
ADD DI, BX ; DI WILL HOLD POINTER INTO UPPER 1/2 LIST
MOV AX, DI
MOV LOWHLFTOP, AX ; REMEMBER TOO FAR FOR LOWER 1/2 LIST
ADD AX, BX
MOV UPPHLFTOP, AX ; REMEMBER TOO FAR FOR UPPER 1/2 LIST
L3: CMP DX, LOWHLFTOP
JE L4 ; SKIP AHEAD IF DONE WITH LOWER 1/2 LIST
CMP DI, UPPHLFTOP
JE L5 ; SKIP AHEAD IF DONE WITH UPPER 1/2 LIST
MOV BP, DX ; OTHERWISE, GET WORD FROM LOWER 1/2
MOV AX, [BP]
MOV BP, DI ; COMPARE WITH WORD FROM UPPER 1/2
CMP AX, [BP]
JL L5 ; SKIP AHEAD IF LOWER 1/2 WORD IS SMALLER
L4: MOV BP, DI
MOV AX, [BP] ; TAKE FROM UPPER 1/2 LIST (IF SMALLER)
ADD DI, 2 ; ADVANCE UPPER 1/2 POINTER
JMP L6
L5: MOV BP, DX
MOV AX, [BP] ; TAKE FROM LOWER 1/2 LIST (IF SMALLER)
ADD DX, 2 ; ADVANCE LOWER 1/2 POINTER
L6: MOV BP, SI ; PUT SMALLER OF THE TWO WORDS INTO ORIGINAL LIST
MOV [BP], AX
ADD SI, 2 ; ADVANCE POINTER FOR ORIGINAL LIST
LOOP L3
MOV AX, BX ; FIX SP BEFORE RETURNING
SHL AX, 1
ADD AX, SP
MOV SP, AX
RET
MSORT ENDP
END MAIN