Файл: Introduction to Microcontrollers. Architecture, Programming, and Interfacing of the Motorola 68HC12 (G.J. Lipovski, 1999).pdf
ВУЗ: Не указан
Категория: Не указан
Дисциплина: Не указана
Добавлен: 14.06.2025
Просмотров: 1426
Скачиваний: 0
274 Chapter 9 Implementationof C Procedures
9.4 Loop Statements, Arrays, and Structs
In this section, we show how statements within a loop can be repeated until a condition is met, governed by an expression much like the expressions of the conditional statements. First, we consider an accumulation of variables incremented or decremented in the loop, in different loop constructs. Then we discuss array elements accessed using indexes. Struct elements are accessed using AND, OR, and shift operations. We will access a two-dimensional array using indexes in for loops and a struct in a do while loop.
The for and while statements test the condition before the loop is executed and are useful if, for example, a loop may have to be done 0 times. The do while statement performs the statement once before it tests the condition. See Figure 9.10.
int i;
main(){ int j, k; |
|||||
for(j = k = 0; |
j != i; |
j++) k += |
j; |
||
while(j != 0) |
k += —j; |
||||
do k += j—; while (j |
!= i); |
||||
} |
|||||
a. A C Program |
|||||
* 3: |
for(j = k = 0; |
j != i; |
j++) k += |
j; |
|
00000802 |
C7 |
CLRB |
|||
00000803 |
87 |
CLRA |
|||
00000804 |
B745 |
TFR |
D,X |
||
00000806 |
2005 |
BRA |
*+7 |
;abs = 080D |
|
00000808 |
1AE6 |
LEAK |
Df X |
||
0000080A |
C30001 |
ADDD |
#1 |
||
0000080D |
BC0800 |
CPD |
$0800 |
||
00000810 |
26F6 |
BNE |
*-8 |
;abs = 0808 |
|
* 4: |
while(j != 0) k += —j; |
||||
00000812 |
2005 |
BRA |
*+7 |
;abs = 0819 |
|
00000814 |
830001 |
SUBD |
#1 |
||
00000817 |
1AE6 |
LEAK |
D,X |
||
00000819 |
0474F8 |
TBNE |
D,*-5 |
;abs = 0814 |
|
* 5: |
do k += j—; while (j != i); |
||||
0000081C |
1AE6 |
LEAK |
D,X |
||
0000081E |
09 |
DEX |
|||
0000081F |
BC0800 |
CPD |
$0800 |
||
00000822 |
26F8 |
BNE |
*-6 |
;abs = 081C |
|
00000824 |
3D |
RTS |
|||
b. Assembly Language developed from Part (a)
Figure 9.10.For, While, and Do While Loops
9.4 Loop Statements, Arrays, and Structs |
275 |
In Figure 9.10 a for loop has an initialization expression, shown first in the for list of expressions; a test expression, shown in the middle; and a loop termination expression, shown last:
* 3: |
for(j = k = 0; j != i; j++) k += j; |
||
CLRB |
; j in D |
||
CLRA |
|||
TFR |
D, X |
; k in X |
|
BRA |
LI |
; do the test before the loop is done once |
|
LO : |
LEAX |
D, X |
; this is the statement that is executed in the loop |
ADDD |
#1 |
; this is the expression done after each loop is done |
|
LI: |
CPD |
$0800 |
; this is the loop test |
BNE |
LO |
||
A while loop has a test expression that is executed before the loop is executed once:
* 4: |
while(j != |
0) k += — j ; |
|
BRA |
L3 |
; do the test first |
|
L2 : |
SUED |
#1 |
; these are the two statements |
LEAX |
D,X |
; that are executed in the loop |
|
L3 : |
TBNE |
D,L2 |
; this is the loop test |
A do while loop has a test expression that is executed after the loop is executed:
* 5: |
do k += j—; while (j != i); |
||
L4 : |
LEAX D, X |
; these are the two statements |
|
DEX |
; that are executed in the loop |
||
CPD |
$0800 |
; this is the loop test |
|
BNE |
L4 |
||
Figure 9.11 illustrates nested for loops and the two-dimesional array index addressing mechanism. This example shows how loop statements can themselves be loops, in a nested loop construction, and how optimizing compilers make loops more efficient. The outer for loop, for (i = sum = 0 ; i < 10; i++) is encoded asan initialization:
CLRA |
; generate 0 |
|
CLRB |
; in high and low bytes |
|
STD |
$08 IE |
; store to clear sum |
STAB |
1, SP |
; store to clear i |
and by the outer loop termination:
INC |
1, SP |
; count up |
LDAA |
1, SP |
; get the variable to be tested |
CMPA |
#10 |
; compare against 10 |
BCS |
*-40 |
; loop as long as i is less than 10 |
CMPA |
#3 |
; check if another iteration is to be done |
BCS |
*-30 |
; if so, branch to the instruction following the initialization |
276 |
Chapter 9 Implementation of C Procedures |
unsigned char a[10][3]; int sum; main() { unsigned char i, j;
for(i = sum= 0 ; i < 10; i++) for(j=0; j < 3; j++)
sum +=£ a[i][j];
>
a.A C Program
4:main() { unsigned char i," j;
0000095B 3B |
PSHD |
5:for(i = sum = 0; i < 10; i++)
0000095C C7 |
CLRB |
|||
0000095D |
87 |
CLRA |
||
0000095E |
7C081E |
STD |
$081E |
|
00000961 |
6B81 |
STAB |
1,SP |
|
6: |
for(j = 0; |
j < 3; |
j++) sum += a[i][j]; |
|
00000963 |
6980 |
CLR |
0,SP |
|
00000965 |
E681 |
LDAB |
1,SP |
|
00000967 |
87 |
CLRA |
||
00000968 |
CD0003 |
LDY |
#3 |
|
0000096B |
13 |
EMUL |
||
0000096C |
B745 |
TFR |
D,X |
|
0000096E |
E680 |
LDAB |
0,SP |
|
00000970 87 |
CLRA |
|||
00000971 |
1AE6 |
LEAK |
D,X |
|
00000973 |
E6E20800 |
LDAB |
2048,X |
|
00000977 F3081E |
ADDD |
$081E |
||
0000097A |
7C081E |
STD |
$081E |
|
0000097D |
6280 |
INC |
0,SP |
|
0000097F A680 |
LDAA |
0,SP |
||
00000981 |
8103 |
CMPA |
#3 |
|
00000983 |
25EO |
BCS |
*-30 |
;abs = 0965 |
5:for(i = sum = 0; i < 10;i++)
00000985 |
6281 |
INC |
1,SP |
00000987 |
A681 |
LDAA |
1,SP |
00000989 |
810A |
CMPA |
#10 |
0000098B |
25D6 |
BCS |
*-40 ;abs = 0963 |
7: } |
|||
0000098D |
30 |
PULX |
|
0000098E |
3D |
RTS |
b. AssemblyLanguage developed from Part (a)
Figure 9.11. Array ManipulationProgram
278 |
Chapter 9 Implementation of C Procedures |
struct spiDevice{
unsigned int spie:l,spe:l,swom:l,mstr:lfcpol:lrcpha:l,ssoeil, lsbf:l;
} *spiPtr = (struct spiDevice *)OxdO; #define spi (*spiPtr)
raain() { spi.spe = 1; |
do ; while(spi.spe); } |
|||
a. A C Program |
||||
0000095B |
3B |
PSHD |
||
0000095C |
FE0800 |
LDX |
spiPtr |
|
0000095F |
6E80 |
STX |
0,SP |
|
00000961 |
OC0040 |
BSET |
0,X,#64 |
|
00000964 |
EE80 |
LDX |
0,SP |
|
00000966 |
OE0040FA |
BRSET |
0,X,#64,*-6 |
;abs = 0964 |
0000096A |
30 |
PULX |
||
0000096B |
3D |
RTS |
||
b. Assembly Language developed from Part (a)
Figure 9.13. A Program Setting and Testing a Bit
The do while statement in Figure 9.13a tests the condition after the loop is executed at least once, but it tests the result of the loop's activities. This is very useful in I/O software because it lets you get data within the statement and test the result in the conditional expression, which is not executed until the statement is executed at least once. See Figure 9.13. The program sets a bit of a struct and tests it repeatedly until it is cleared (by hardware). It is compiled into assembly language shown in Figure 9.13b. The struct definition shown below merely defines accesses using the pointer spiPtr. The elements can be accessed using "arrow" notation. For instance the bit spe can be
set using spiPtr->spe |
= 1; However, by declaring #define spi (*spiPtr), the |
expression spi. spe = |
1; can be used instead. This is encoded into assembly language |
using the BSETinstruction: |
|
BSET 0, X, #6 4 |
; set bit 6 of location pointed to by X (the spi port) |
The statement do ; while (spi. spe); is implemented with
BRSET 0, X,#6 4 , * - 6 ; wait while bit 6 of location OxDO is 1
Generally, if the bitfield is more than one bit, data to be inserted will have to be shifted to the correct bit position, and masked parts of it are ORed with masked parts of bits in other fields, to be written into the memory. This code looks like the code for statement lui = (lui « 3) + (lui « 1) + Isc - ' 0 ' ; that westudied at theend of Section 9.2. Data read from such a bitfield will have to be shifted and masked in like manner.
280 |
Chapter 9 Implementation of C Procedures |
int a;
void main() { int |
b; b = power(&a, 2); } |
||||||
int |
power(int |
*i, |
unsigned |
char |
j ) { int |
n ~ 1; |
|
while( |
j— |
) n = n |
* *i; |
return |
n; |
||
} |
|||||||
a. A C Procedurecalling a Subroutine |
|||||||
00000976 |
CC0800 |
LDD |
#2048 |
||||
00000979 |
3B |
PSHD |
|||||
0000097A |
C602 |
LDAB |
#2 |
||||
0000097C |
07DD |
BSR |
*-33 |
;abs = 095B |
|||
0000097E |
3A |
PULD |
|||||
0000097F |
3D |
RTS |
|||||
b. Assembly Language for the Calling Procedure in Part (a)
0000095B CE0001 |
LDX |
#1 |
||
4: |
while( j— ) |
n = n * *i; |
||
0000095E |
B710 |
TFR |
B,A |
|
00000960 200B |
BRA |
*+13 |
;abs = 096D |
|
00000962 ED82 |
LDY |
2,SP |
||
00000964 36 |
PSHA |
|||
00000965 |
EC40 |
LDD |
0,Y |
|
00000967 B756 |
TFR |
X,Y |
||
00000969 |
13 |
EMUL |
||
0000096A |
B745 |
TFR |
D,X |
|
0000096C |
32 |
PULA |
||
0000096D |
36 |
PSHA |
||
0000096E |
43 |
DECA |
||
0000096F |
E6BO |
LDAB |
1,SP+ |
|
00000971 |
26EF |
BNE |
*-15 |
;abs = 0962 |
5:return n;
00000973 |
B754 |
TFR |
X,D |
00000975 |
3D |
RTS |
c. Assembly Language for the Called Procedure in Part (a)
Figure 9.14. A Subroutine to Raise a Number to a Power
SP-> inside the subroutine
Figure 9.15. Stack for power Procedure