; SORTINT.ASM - assemble with MASM 5.1 or compatible assembler
; - for QB4.x / PDS
; - written by Brian McLaughlin. Released to public domain.
;
; This SUB sorts an array of integers, using the Combsort
; algorithm. You pass it the first element of the array,
; and the number of elements to sort. In this way, SortInt can
; be used to sort a only a part of an integer array, if desired.
; The sorted order is ascending.
;
; DECLARE SUB SortInt (SEG ArrayFirstElement%, NumOfElements%)
;
; Example:
; FirstElem% = LBOUND(IntArray%)
; TotalElem% = UBOUND(IntArray%) - FirstElem% + 1
; SortInt IntArray%(FirstElem%), TotalElem%
.MODEL MEDIUM, BASIC
.CODE
Gap DW ? ; put variable in code segment
SortInt PROC USES DS ES DI SI, Addr:DWORD, Elems:WORD
Mov BX, Elems ; point BX at Elements
Mov CX, [BX] ; CX = Elements
Jcxz SortExit ; gee, no elements to sort!
Mov BX, CX ; BX = Elements
Mov Gap, CX ; copy it into Gap, too
Lds SI, Addr ; point DS:SI at first element
Push DS
Pop ES ; point ES at array's segment
Do: ; calculate the value of Gap into AX/memory
Push BX ; save BX, we're gonna trash it
Mov AX, Gap ; AX = current value of Gap
Xor DX, DX ; prepare DX to receive any rotated bits
Mov CX, 3 ; we'll shift all bits left 3 positions
MultBy8:
Shl AX, 1 ; multiply (Gap * 8) into DX:AX
Rcl DX, 1 ; catch any carried bits
Loop MultBy8 ; go around CX times
Mov BX, 11 ; dividing by 11
Div BX ; divide DX:AX by 11
Or AX, AX ; AX holds quotient, so see if AX = 0
Jnz CalcDone
Mov AX, 1 ; if Gap < 1 then Gap = 1
CalcDone:
Mov Gap, AX ; leave newly calculated value in Gap
Pop BX ; restore BX
Xor DX, DX ; set switch to zero
Mov CX, BX ; CX = Elements
Sub CX, AX ; CX = the FOR loop counter (Elements - Gap)
Mov DI, AX ; DI = Gap
Shl DI, 1 ; convert DI into a memory offset
Add DI, SI ; point DS:DI at Array%(J%) [I%+Gap%]
Push BX ; Save value of Elements
Push SI ; save offset of first element
For:
Mov BX, [DI] ; load BX with value at DS:DI [Array%(J%)]
Lodsw ; load AX with value at DS:SI [Array(I%)]
Cmp AX, BX ; same as IF AX > BX THEN
Jle IfEnd ; if AX <= BX, then skip ahead
Stosw ; puts AX into ES:DI (points to Array%(J%))
Sub DI, 2 ; the Stosw added 2, but we want to do that manually
Mov [SI-2], BX ; puts BX into Array%(I%) [Lodsw inc's SI+2]
Inc DX ; set switch to a non-zero value
IfEnd:
Add DI, 2 ; point DI ahead in tandem with SI
Loop For
Pop SI ; DS:SI points to first element of array
Pop BX ; BX = Elements
Or DX, DX ; did we swap any elements?
Jnz Do ; if we did, go around again
Mov AX, Gap
Cmp AX, 1 ; does Gap = 1?
Jne Do ; if not, go around again
SortExit:
Ret
SortInt ENDP
END
--
Brian McLaughlin, Technical Writer |"Thanks to the Internet, misinformation
Integrated Measurement Systems, Inc.| now travels faster than ever before!"
Beaverton, OR, USA | ---- Standard disclaimer applies ----