Reprinted with permission from American Laboratory, Vol. 11, No. 10, pp. 133-136. Copyright 1979 by International Scientific Communications, Inc. Microcomputer interfacing Q Sorting By Christopher A. Titus, Peter R. Rony, David G. Larsen, and Jonathan A. Titus UITE OFTEN, a program will execute much. faster if the values it accesses are sorted. Sorting also is useful when data values or alphanumeric strings have to be' output to a printer or a cathode-ray tube (CRT) in a specific order. Sorting is defined as the rearrangement of data values in a list, table, record, or file in an ascending or descending order. If the data values consist of alphanumeric strings, then the strings will be sorted in alphabetic or alphanumeric order. A number of different methods can be used to sort data, including: straight insertion sort, binary insertion sort, Shell's sort, bubble sort, quick sort, heap sort, merge-exchange sort, and two-way merge sort. In general, all of these sorting methods can be classified as one of the following sorting methods: insertion method, exchange method, selection method, merge method, distribution method. J ,2 This column discusses only the exchange method of sorting numeric values. Specifically, this column is concerned with the bubble sort method. This method is perhaps one of the slowest methods that can be used. However, it is probably easier to write a bubble sort subroutine than any other type of sort subroutine. As an example of the use of the bubble sort method to sort numeric values that are stored in a list, assume that a certain list contains five eight-bit unsigned data values (nodes), as shown in Table 1. The list is stored in memory from memory location X to memory location X + 4. If the data value (node) in memory location X is greater than the data value in memory location X + I, the two values are exchanged. This means that the data value in memory location X is written into memory location X + I, and the value previously stored in memory location X + I is stored in memory location X. Because an exchange has just taken place, a register or memory location is loaded with a specific value to indicate that an exchange has taken place. If the data value in memory location X is less than the data value in X + I, no exchange takes place. This assumes that we want to sort the list in ascending order, where the smallest data value eventually will be stored in memory location X and the largest data value eventually will be stored inX + 4. Whether or not an exchange takes place, the microcomputer next compares the data values in memory locations X + I and X + 2.. If the content of memory location X + I is greater thanX + 2, an exchange takes place. If the content of memory location X + I is less than the content of memory location X + 2, no exchange takes place. This compare-and-exchange process continues until the microcomputer reaches the end of the list. When the end of the Jist is reached, the microcomputer examines the content of a register or memory location to see if any exchanges took place. If any did, the micro- Table 1 Bubble sorting a list of data Memory address X X+1 X+2 X+3 X+4 Dr. C. Titus is Consultant, and Dr. J. Titus is President, Tychon, Inc. Dr. Rony, Department of Chemical Engineering, and Mr. Larsen, Department of Chemistry, are with the Virginia Polytechnic Institute and State University. Initially 3 2 5 4 1 1st pass 2nd pass 3rd pass 4th pass 5th pass 3 2 2 1 2 2 3 3 1 2 4 5 1 3 3 4 1 4 4 4 1 5 5 5 5 Results 2 2 2 1 1 3 3 1 2 2 4 1 3 3 3 1 4 4 4 4 5 5 5 5 5 79 b ITHIS Sll1JROUTUJE USES T;'lE bUBbLE SORT ALGORITHC1 ITO SORT SINGLE PRE,CISIO'J (a-bIT>, l!c,SIGNED INtJtluERS STORED 1:\1 t1E,;'lOHY. E'JTER THIS SUbROUTl"JE IWITH THE STARTI~G ADDRESS OF THE LIST I(T'IE LQIoTER /-IDDRESS> I:-J REGISTEH PAIR H AcJD THE IFlNkL ADDHESS IeJ REGI STER PAL R D. usorrr. PASSl, t10 VAle SUBL f10VEA ,'lOVAD SbbH MOVDA PlISHH 01lS1I D f1VI C 000 '-'PI, f10\!/-I'1 INXH C'1 Prl JC N r.XT o J~ NEXT o no VbM t10vt1k LJCXH '3E~<T, !101/MB INXrI MVI C 377 DCXD "10VAD Of{kl:: ,JN7. UPl IGET THE,LO bYTE OF TilE dIGHEST ADDRESS ISUbTRkCT THE BEGI~~I~G LO ADDRESS ISAVE THE RESl'LT H E IGET r-n: HI BYTE OF THE HIGHEST ADDRESS I SUBTHACT THE BEG!"J'J I~JG n r ADDRESS ISJO\VE THE HESl'LT DJ LJ ISkVE TdE I'JITIAL ADDl1ESS ISAVE THE bYTE COU1T O~ THE STAC~ ITllE C REGISTER IS USED TO !'JDICATE I I F AI EXCHf-I'JGE TA;CES PLACE IGET A 'lODE FROM THE LI ST I 1-, CHEt1 E"JT H&L TO THE N EXT xo DE ICQr1PARI:: A A'JD ME,,1ORY I IF '1E!'10hY > 1\, DO NOT EXC!-lA'IlGE ITdUl. I',STEAD, EXAi1I'JE THE 'lEXT TWO I~'ODES 1:. THE LI ST I I F TilEY ARE ECl:AL, DO 'JOT IEXCdf-l',GE THFl EITHER ISAVE. THE: CO.'JTE"T OF ME:l0RY 1'3 Ii ISAVE THE: CONTE:'-IT OF A IN ,1D1ORY /lJACI( UP ] t1P10HY LOCATIO'I AND ITHEJ SI-IVE TJiE CO:,TE!'JT OF b I:'l NE,;10RY I1NCHEf1LJT T;tE PST ADDR.ESS ITHE C HEGI STER IS l'SElJ TO I'JDl GATE ITHAT A'J E;:{CIiA.1GE liAS TAKE'J PLACE IDE.G!<E..'lE'JT TdI:: GOl."JT I I S Tli E CO lI'JT U0 0 ? IdAVE ILL ST, ~OT CHECKED TdE E1TIRE Sf) ){EEP CHECi(l'JG o ~10\lAC OHAA POPD DOP:-l J-g !>ASSI U nET IGET THE EXC;1i-dGf, I!JDI GATOR UTO ITdE l-\ HEGI STEFl. I\'JD SET THE FLAGS ILlJkD {;",r: '.v I Td TdE bYTE COl'~lT ILOAD H&L WITrl TdE I~ITIAL ADDRESS IA\J EXCf-lh'JGE OGCUO{RJ::D, SO EXA,'ll'JE ITdE LI ST lJ~E :10l'tE Tlt1E I RETl.1mJ ',J;{ E 'J ~'JO l::XCrlA, GES T /~i{ E PI.. AC E Figure 1 A ltst-sort subroutine that uses the exchange method (bubble sort), computer has to make another pass through the list. Only when the microcomputer makes a pass through the entire list, and no exchanges take place, is the list sorted, Table I contains a list that is bubble sorted. On the first pass through the list, the three and the two are exchanged. The five and the four also are exchanged, followed by the five and one. The largest value in the list (five) is bubbled up to the top of the list. On the second pass, the four is. bubbled up to memory location X + 3, just behind the five. The three and two are bubbled up to their appropriate positions in the list in the third and fourth passes. On the fifth pass, the data values are in the proper sequence. No exchanges take place, therefore the list is sorted. A 80 bubble sort subroutine for the 8080, which can be used to sort eight-bit unsigned numbers, is listed in Figure 1. The BSORT subroutine must be called with the starting address of the list in register pair H and the final address of the list in register pair D. If the list in Table I is to be sorted by the BSORT subroutine, register pair H would contain the address X and register pair D would contain the address X + 4, Starting at BSORT, the 8080 subtracts the starting address (X) from the final address (X + 4) and saves the result (the node count) in register pair D. The node count is used to indicate to the 8080 when it has reached the end of the list. At PASSl, the starting address of the list (X) and the node count are saved on the stack. The C register is loaded with 000, because it will be used as the exchange indicator. If an exchange takes place during a pass through the list, the C register will be set to 377. This means that when the 8080 has examined all of the nodes in the list, it will examine the content of the C register to see if any exchanges took place during the last pass through the list. If the C register contains 377, at least one exchange took place, so the 8080 will have to make another pass through the list. The 8080 begins the actual compare-and-exchange instructions at UP!. The first node is moved to the A register, and the memory address in register pair H is incremented by one to X + I. The two in memory location X + I then is compared to the three in the A register. If the content of X + 1 is equal to or greater than the content of the A register, the 8080 jumps to NEXT. This means that no exchange should occur. If the content of memory (two) is less than the content of the A register (three), the node in memory is moved to the B register and the content of the A register is stored in memory. The memory address is then decremented (X + I to X) and the node in the B register (two) is written back into memory. The memory address is then incremented (to X+' I). The C register is loaded with 377 because an exchange just took place. By decrementing the node count contained in register pair D, the 8080 can determine if the entire list has been examined. If it has not, the 8080 jumps back to UPl, where the three in X + 1 is compared to the five in X + 2. As expected, these two nodes are not exchanged. The next time through the UPl loop, the 8080 compares and exchanges the five in X + 2 with the four in X + 3. The next time that the UPl loop is executed, the five in X + 3 is compared and exchanged with the one in X + 4. At this point, the node count in register pair D is decremented to zero. Because of this, the 8080 examines the content of the C register. If the content of the C register is nonzero (377), the 8080 jumps back to PASSI so that it can make another pass through the list. The 8080 will con"tinue to make passes through the list *050 000 i;SS 16, ~10VA£ SUbL ~i0V£H PASS I, MOVAD SDbH RRC MOVDA '10VA£ RRC MOVEA PUSHH PUSH 0 t1VI C 000 UPl, PUSHD MOVI::I1 INXH MOVDM INXH I'lJXH MOVAM XRAD JM POSN EG IGET TiiE FI'JAL ADDRESS (LSbY> IS1.!BTRHCT THE PJITIHL ADDRESS (LSBY> ISAVE THE RESVLT (LSUY> IGET THE FINAL HDliRESS (MS8Y) ISUbTRHCT THE INITIHL ADDRESS (MSBY) IDI\lID£ THE RESULT bY TWO lAND SAVE IT ITHE'1 DIVIDE THE LSUY OF THE I REStJL T BY TWO ISAVE THE START.!'IJG ADDRESS OF THE LIST I SAVE THE NODE COU'lJT I SET THE EXCHA\lGE I~'1DI CATOR TO IZERO I SAVE THE 'lODE COU'lT IGET rn i; LSBY OF A NODE IINCREMEJ'lT THE: MEMORY ADDRESS IGET THE MSBY OF THE SAME NODE II'lJCREMEi'lT THE ADDRESS TloJICE ITO THE MSbY OF THE NEXT ,'lODE IGET ITS riSbY I'JTO THE A REGISTER IEX'OR IT WITH THE tiSbY 1'1 D. I I F ONE OF THE "1UMBERS IS "1EGIATIVE, FI:'1D OUT WHICH O"1E o SUH2, DCXH MOVAE SUBM MOVBA INXH MOVAD SHBM JC DW"11 o onAb JZ DHN I o EXCH, O;(AS IS, MOVI3M MOVMD DCXH MOVCM MOVME DCXH MOVMB DCXH MOVMC I"1XH I"1XH MVI C IGET THE ~1S13Y OF THE SECO"1D /I ISAVE THE MSbY OF THE FIRST IDECREME..'lT TO THE LSBY IGET THE LS8Y OF THE SECOND /I ISAVE THE LSBY OF THE FIRST (I IDECRL'1ENT TO THE MSBY ISAVE THE MSI:JY OF THE SECO"1D /I IDECREliE"1T TO THE LSBY ISAVE THE LSBY OF THE SECO'JD/I I I:IICREME'1T TO THE MSBY ITHEN TO THE LSBY ITHEJ SET THE EXCHA'iGE I'lDICATOR ITO POPD DCXD MOVAD ORAE J"J7.. UPI IPOP THE '/ODE COU'JT IDECREME.."JT IT IGET THE MSHY OF THE "10DE COU"1T lOR IT 'NlTH THE LSBY II S THE cous r 7..ERO? rIO, THEN IEXAMI,'iE; THE "1EXT TWO :-lODES. POPD POPH MOVAC ORAA J'\JZ nASS I IYES, POP THE SECO·'1D 'iODE COtNT IA'lD THE STAR1"UG ADDRESS OF ITHE LIST. WHAT IS THE STATE OF ITHE E.'<:CHA'IGE I~'1DICATOR? IAN EXCH/,'lGE TOOK PLACE, SO IE"{A,1UE THE LIST AGA1"'J; RET 1"10 EXCHA\JGES TOOI( PLACE, MOVAM lIS THE 'JEGATIVE :'lUMBER IN MEMORY? Ji'l EXCH o IYES, THE'J IT IS LESS THAN THE IPOSI Tl VE Ntr.iBER 1"1 REGI STER I PAl R D. DCXH JMP O;(ASI S IDECREME,'n TO THE LSBY I AND TH B'1 EXAM 1'1 E TH E ;'1 EXT TWO INODES IN THE LI ST o DWN I, GET O-"1E or THE :1SBYS ISUBTRACT THE OTHE:R ICONTE.''lT OF MEMORY I S LARGER ITHA'I THE CONTENT FO REGI STER I PAl R D, SO THE a RD.ER I S CORRECT 1"10 CARRY, ARE THEY EQUAL? IYES, THElJ DO NOT EXCHA'1GE THEM INO\~ 377 o POSNEG, IDECREl1ENT THE ADDRESS TO THE LSBY IHOTH NUMI:JERS ARE POSITIVE OR INEGAT.! VE, SO "COMPARE" THEl1 onAH o 377 RETUR\J. Figure 2 A bubble sort subroutine for tti-bit signed numbers. until the C register contains zero when the node count is decremented to zero. When the C register does contain zero, the 8080 will return from the BSORT subroutine. If desired, signed or floating-point numbers or alphanumeric strings can be sorted using the bubble sort method. Assume that 16-bit signed numbers are to be sorted, and that the sign of the number is stored in the most significant bit of the 16-bit number. If the sign bit is a logic zero, the sign of the number is positive and if the bit is a logic one, the number is negative. The bubble sort subroutine listed in Figure 2 performs the same operations as the one in Figure 1, except that the difference between the starting and final addresses of the list has to be divided by two, because each 16-bit number (node) requires two eight-bit memory locations for storage. Also, the 8080 cannot execute any 16-bit comparison instructions, so two eight-bit subtractions must be performed. Perhaps the biggest difference between the two subroutines is that the 8080 has to check the signs of the two nodes being compared. If the sign of both numbers is the same (both positive or negative), the 16-bit comparison can be performed as usual. However, if the sign of the two numbers is different (one number is positive and one number is negative), the 8080 has to ensure that the positive number is stored in the higher memory locations. In Figure 2, the 8080 first subtracts the starting address in register pair H from the final address in register pair D. Note that the final address is the address where the least-significant byte (LSBY) of the last number is stored. After the 16-bit final address is subtracted, the 16-bit result is rotated once to the right, because each node requires two memory locations for storage. Note that the most significant byte (MSBY) of the result is rotated to the right first, followed by the LSBY. At PASS), the starting address of .fhe list and the node count are saved on the stack. The C register is set to zero to indicate that no exchanges have taken place. Starting at UP), the node count in register pair D is again saved on the stack. The first 16-bit 81 i node then is moved to register pair D. The LSBY of the node is moved to the E register and the MSBY (including the sign bit) is moved to the D register. The address in register pair H is incremented twice, so that it addresses the memory location containing the MSBY and sign bit of the second node. The MSBY's of both nodes are then exclusive-oa'd, and if the signs of the numbers are different (one is positive and one is negative), the 8080 jumps to POSNEG. If the 8080 jumps to POSNEG, it has to determine which number is positive and which is negative. To accomplish this the 8080 gets the MSBY from the node in memory, and performs an OR operation with itself to set the 8080's flags. If the number in memory is negative, the 8080 jumps to EXCH, so that the negative number is moved to a lower memory address and the positive number is moved to a higher memory address. If the number in memory is positive, the two numbers are in the proper order, so the 8080 simply jumps to OKASIS when the node count is decremented and the exchange indicator is examined. If both numbers are positive or negative, the 8080 does not execute the JM to POSNEG, stored in memory just before SUB2. Instead, the 16-bit number in memory is subtracted from the 16-bit number in register pair D. If the content of memory is greater than or equal to the content of register pair D, the 8080 jumps to DWNl, because the numbers are in the proper order. If the content of memory is less than the content of register pair D, the 8080 executes the instructions at EXCH. The instructions at EXCH move the node addressed by register pair H to register pair B. The larger of the two nodes then is moved from register pair D to memory. The memory address in register pair H then is decremented, so that the smaller node in register pair B can be saved in memory, at a lower memory address. The two nodes now have been exchanged, so the exchange indicator (the C register) is set to 377. Whether or not an exchange has taken place, the 8080 executes the instructions at OKASIS when two nodes 82 have been compared (and exchanged, if required). The instructions at OKASIS cause the node count to be popped off of the stack. The node count then is decremented and examined to see if it is equal to zero. If it is not (meaning that there are additional nodes in the list that must be ex" amined), the 8080 jumps back to UPI, where the decremented node count is saved on the stack and the compare-and-exchange instructions are executed again. If the node count is decremented to zero, the JNZ to UPI is not executed. The 8080 has completed a pass through the list, so it must check the state of the exchange indicator. To do this, the 8080 pops the original node count and the starting address of the list off the stack. The exchange indicator then is moved to the A register, where it performs an OR operation with itself. If an exchange took place during the last pass through the list, the 8080 jumps back to PASS\. If this happens, register pair D contains the node count and register pair H contains the starting address of the list. If no exchanges took place during the last pass through the list, the content of the C register is zero, so the 8080 returns from the BSS16 subroutine. The 16bit signed numbers contained in the list have been sorted. As mentioned earlier, sorting lists are necessary because a program may execute faster if it has to access these lists or alphanumeric strings may have to be sorted before being printed. There are a number of other sorting methods that can be used to sort data. Many of these methods are much faster than the bubble sort method, but there are very few that are easier to write. References I. KNUTH, D.E. The Art of Computer Programming, Vol. 3, Sorting and Searching (Addison-Wesley, Reading, MA,1973). 2. TITUS, C.A. 808018085 Software Design, Book 2. Asynchronous Communications, Interrupt and Data Structure for 8080- and 8085-based Microcomputers (Howard W. Sams & Co., Indianapolis, IN, 1979).
© Copyright 2024