One of the most prevalent activities on a computer is the need to copy data from one location to another (i.e., memory to the processor, processor to I/O, etc.). Typically, the data consists of more than one byte. In chapter 3, the function of a set of data movement instructions was presented. Three types of movement are directly supported by the HC11: memory to processor register, processor register to memory and processor register to processor register. The program in this section will demonstrate a method of copying a block (one or more bytes) from a range of memory locations to another range of memory locations; thus it is a memory-to-memory movement. The data movement instructions, load and store, will be utilized with the indexed mode of addressing to methodically copy the block. A flowchart for this program is shown in Figure 5.12, and the source code listing to implement the program is shown in Figure 5.13.
The program starts by initializing the source and destination addresses. The X register holds the source address, and the Y register holds the destination address. The address of the first location of the source is $0000. The address of the first location of the destination is $0180. The numbers are read from each source location and written to
0001 *Program to count the positive numbers 0002 *in a list using index mode
0003
0004 0160 4f CLRA ;Clear COUNT
0005 0161 ce 01 80 LDX #$0180 ;Initialize the base address 0006 0164 e6 00 LOOP LDAB $00,X ;Get a number
0007 0166 2b 01 BMI PAST ;If negative, don't count! 0008 0168 4c INCA ;Else, Count the positive 0009 0169 08 PAST INX ;Increment base address 0010 016a 8c 01 a0 CPX #$01A0 ;Is list finished? 0011 016d 26 f5 BNE LOOP ;If not finished, LOOP 0012 016f 3f SWI
Figure 5.11 Code to Count Positive Numbers in a List
1. How many bytes does this program occupy in memory? 2. What address value is assigned to the label “LOOP”? 3. How many numbers are in the list?
131
each destination location one-by-one, until the entire block is copied. The load instruction in line 6 reads the source data from memory and temporarily holds it in AccA. Then the store instruction in line 7 writes this data from AccA to the destination address. Since the source and destination locations are changing, both index registers must be incremented each time through the loop. The program determines if the copy operation is complete by comparing the destination address to the first address beyond the destination range. The CPY instruction in line 10 accomplishes the check in preparation for the branch test in line 11. As has been shown before, if the destination is not equal to the address beyond the end of the range, then the process loops until the copy operation is complete.
Copy a Block Initialize Source Address Initialize Dest. Address COPY Get a number
Store the number in Destination Increment Pointer No Finished? Yes End
Figure 5.12 Flowchart to Copy a Block of Numbers
0001 *Program to copy a list of numbers
0002 *using index mode from $0000 - $0009 to $0180 - $0189 0003
0004 0100 ce 00 00 LDX #$0000 ;Init source address 0005 0103 18 ce 01 80 LDY #$0180 ;Init destination address 0006 0107 a6 00 COPY LDAA $00,X ;Get a number from source 0007 0109 18 a7 00 STAA $00,Y ;Store the number in dest 0008 010c 08 INX ;Increment pointers 0009 010d 18 08 INY
0010 010f 18 8c 01 8a CPY #$018A ;Finished? 0011 0113 26 f2 BNE COPY ; If NOT, do again! 0012 0115 3f SWI
Figure 5.13 Code to Copy a Block of Numbers
132
Self-Test Questions 5.5
Summary
The indexed addressing mode is a method of addressing memory that uses a 16-bit base address in conjunction with an 8-bit unsigned offset. The advantage of the instructions that use this mode is that they allow a program to loop through memory, operating on different bytes in a list each time through the loop. Five examples were presented in this chapter: two methods of summing a list of numbers, a means of finding the largest number in a list, the means of counting the number of positive numbers in a list and a method of copying a block of data from one memory area to another. Each of these examples used one or both of the index registers as a base address to reference the data in the list or block.
Chapter Questions
1. What is the effective address of the following instruction if the X register contains $0120: LDAB $20,X?
2. What is the effective address of the following instruction if the Y register contains $B629: LDAB $D7,Y?
3. What is the effective address of the following instruction if the X register contains $0005: CPX $01,Y?
4. Using the data in Figure 5.14, express the results of the following instructions, including status of the condition code flags. Which addressing mode is used for each instruction? What is the opcode (including prebytes) of each instruction? NOTE: Each instruction is independent. The results are not cumulative. a. LDAA $F9,Y b. STX $01,X c. CLR $00,X d. DEX e. LDD $1A,X f. TSX g. STS $01,X h. CMPB $07,X i. TST $E2,Y j. LSR $FB,Y
1. Since two index registers are being used, what is the maximum distance between the source and destination ranges?
2. Why are there four bytes of machine code listed for the CPY instruction on line 10 of Figure 5.13?
3. If the program ends when the destination address is incremented to $018A, what is the last destination address that receives data?
133
5. What is the cost in instructions of using the WHILE loop instead of the UNTIL loop from Figures 5.5 and 5.7?
6. If the block copy program from section 5.5 used a single index register as a base address, what would be the maximum distance of the copy?
Chapter Problems
1. Modify the UNTIL method summation program from Figure 5.5 to do BCD arithmetic instead of hex arithmetic.
2. Draw a flowchart of a program that will count the number of items equal to zero in a list of ten items starting at location $0000.
3. Write a program from the flowchart in problem 2. Assume the list starts at $B600 and ends at $B63F. Be sure to use the appropriate compare instruction.
4. Write a program that will count the negative and positive numbers in a list. Assume the list of numbers starts at $0100 and is 40 bytes long.
5. Given two sequential lists of ten numbers, write a program that will add the numbers in pairs and store the result of each pair in a third list. The first number will be added to the first number of the second list, and the result will be stored in the first position of the third list. The lists start at the following memory locations: $0000, $000A, and $0014.
6. Rewrite the program from Figure 5.13 to copy a block of 24 bytes from $0100–$0117 to $0168–$017F. Use only one index register to establish the base address and use different offsets to designate the source and destination locations used by the load and store instructions. Assemble the code to run starting from location $0000. 7. Rewrite the program from Figure 5.13 to perform the same function presented in
problem 6, except use AccD for the temporary storage location in the processor. Modify the flow of the program to accommodate this double-byte flow of data. The end result of the program should be the same as for the program in problem 6. Which approach is a more efficient use of memory? Which approach is a more efficient use of time (fewer machine cycles)?
Answers to Self-Test Questions
Section 5.1
1. All indexed mode instructions use an unsigned 8-bit offset.
2. $0023 base address
2. + $0062 zero-filled address offset
2. $0085 effective address 134 C = $D0 00F8 00 11 22 33 44 55 66 77 D = $B600 0100 F3 56 E3 DB A1 A0 09 00 X = $0100 0108 22 44 52 88 63 77 74 33 Y = $0016 0110 FF 00 FF 11 FF 22 FF 83 S = $01FF 0118 F1 3B BB B6 D4 AD CE 00 Registers Memory
Figure 5.14 Default Data Set #3
3. All instructions that require two-byte memory access require two effective addresses. The first of the two addresses (M) is calculated using Equation 5.1. The second is simply M + 1.
Section 5.2
1. The offset is fixed in memory, but the HC11 provides instructions to increment the addresses in the index registers.
2. The UNTIL example executes the conditional branch 16 times. The WHILE example must execute it 17 times the way it is written.
Section 5.3
1. An IF-THEN-ELSE structure is used in addition to the WHILE structure. 2. As line 5 is outside the loop, it will be executed only one time.
3. Since the program is finding the largest number, the reference must initially be the lowest number to assure that it cannot be greater than any other number in the list.
Section 5.4
1. The program occupies 16 bytes, $0160–$016F.
2. The label LOOP is equal to the address $0164, where it is defined in line 6. This destination address is used by the assembler to calculate the relative address $F5 that is used in line 11.
3. The list consists of 32 numbers ($01A0–$0180).
Section 5.5
1. Since two index registers are being used, there is no limit on the range except the 64K address boundary of the HC11.
2. Instructions that utilize the Y index register require the prebyte before the opcode. The first byte ($18) is the prebyte, followed by the opcode ($8C), followed by the two-byte immediate data jjkk ($018A).
3. Y = $0189 on the last pass, so the STAA $00,Y instruction writes to $0189 before being incremented to $018A and falling out of the loop.
135
Objectives
After completing this chapter, you should be able to: Sub rou tines
◗ Use push and pull instructions to move data to and from the stack ◗ Organize code into subroutines
◗ Explain the use of subroutine control instructions: JSR, BSR and RTI ◗ Compare efficiency trade-offs between in-line code and code that uses