home *** CD-ROM | disk | FTP | other *** search
- ;This routine is an external procedure that can be called from a Turbo Pascal
- ;program!
- ;
- ;--------------------------------------------------------------------------*
- ; The following are offsets in the stack for the input parameters: |
- ; The invoking statement is: |
- ; |
- ; Sort(var Table; NumRec, FStart, Size: integer); |
- ;--------------------------------------------------------------------------*
- FSize equ 4 ; Size of field to sort
- FStart equ FSize+2 ; Start position within record
- NumRec equ FStart+2 ; Number of records to sort
- Table equ NumRec+2 ; Start column of field
-
- ;--------------------------------------------------------------------------*
- ; Initialize registers for program to use |
- ;--------------------------------------------------------------------------*
- START:
- PUSH BP ; save base page register for Turbo
- MOV BP,SP ; set base pointer equal to stack pointer
- PUSH DS ; Save data segment register
- MOV AX,NUMREC[BP] ; Get number of records to sort (GAP)
- LP1:
- SHR AX,1 ; GAP := GAP DIV 2
- OR AX,AX ; Check for end of sort (GAP = 0)
- JZ DONE ; Exit from module if done!
- MOV BX,AX ; BX = NextEl := GAP
- LP2:
- INC BX ; BX = GAP := GAP + 1
- CMP BX,NUMREC[BP] ; Check for end of first loop...
- JA LP1 ; Exit if NextEl > NumRec
- MOV DX,BX ; DX = SortEl := NextEl - Gap
- LP3:
- SUB DX,AX
- JBE LP2 ; Exit if SortEl <= 0
- PUSH BX ; Save NextEl
- PUSH DS ; Save data segment ptr
- LDS BX,TABLE[BP] ; Get address of pointer table
- MOV DI,DX ; Get SortEl
- DEC DI ; Back up one (table entries start at "1")
- ADD DI,AX ; SortEl + Gap
- SHL DI,1 ; Calculate offset within table
- SHL DI,1 ;
- ADD DI,BX ; Add in starting address of table
- PUSH DI ; Save that offset!
- LES DI,DS:[DI] ; Get address of Table[SortEl+Gap]
- ADD DI,FSTART[BP] ; Add in offset from start of record
- MOV SI,DX ; Get SortEl
- DEC SI ; Back up one (table entries start at "1")
- SHL SI,1 ; Calculate offset within table
- SHL SI,1 ;
- ADD SI,BX ; Add in starting address of table
- PUSH SI ; Save that offset!
- LDS SI,DS:[SI] ; Get address of Table[SortEl]
- ADD SI,FSTART[BP] ; Add in offset from start of record
- MOV CX,FSIZE[BP] ; Get size of field to test
-
- ; Jim, I think this is a quicker way to do a string comparison
- ; Let the machine do the looping!! Work Smarter not Harder!
-
- REPE CMPSB ; Compare Table[SortEl] w/ Table[SortEl+Gap]
- ; Repeat compare as long as they are the same
- ; And CX is non zero.
-
- JBE OK ; If Table[SortEl+Gap] < Table[SortEl] then
- ; skip the swap portion.
-
- ; All this just to do that! Jim, Jim, Jim... Arrr Arrr Arr....
- ;LP4:
- ; CMPSB ; Compare Table[SortEl] w/ Table[SortEl+Gap]
- ; JB OK ; Table[SortEl] < Table[SortEl+Gap]
- ; JNE SWAP ; Table[SortEl] > Table[SortEl+Gap]
- ; LOOP LP4 ; Table[SortEl] = Table[SortEl+Gap]
- ; JMP OK ;
-
-
- SWAP:
- POP SI ; Restore SortEl ptr
- POP DI ; Restore SortEl+Gap ptr
- POP DS ; Restore Data segment register
- MOV BX,DS:[SI] ; Swap segment values
- XCHG BX,DS:[DI] ;
- MOV DS:[SI],BX ;
- ADD SI,2 ; Increment to offset values
- ADD DI,2 ;
- MOV BX,DS:[SI] ; Swap offset values
- XCHG BX,DS:[DI] ;
- MOV DS:[SI],BX ;
- POP BX ; Restore Gap value
- JMP LP3 ; repeat until sorted
- OK:
- POP SI
- POP DI
- POP DS
- POP BX
- JMP LP2
- DONE:
- POP DS ; Restore data segment value
- MOV SP,BP ; reset stack pointer
- POP BP ; reset base pointer
- RET 10 ; Exit from module & clean up stack!
-