Файл: Introduction to Microcontrollers. Architecture, Programming, and Interfacing of the Motorola 68HC12 (G.J. Lipovski, 1999).pdf
ВУЗ: Не указан
Категория: Не указан
Дисциплина: Не указана
Добавлен: 14.06.2025
Просмотров: 1425
Скачиваний: 0
260 |
Chapter 9 |
Implementation of C Procedures |
|||||
unsigned |
char |
guc; |
int |
gsi; |
|||
main(){ |
char |
Isc; |
unsigned |
int lui; |
|||
Isc |
= Isc |
&guc; |
Isc &= 0x12; |
gsi = gsi |
| lui; |
||
gsi |
= gsi |
& 0x1234; lui |
= Isc * guc; lui |
= lui / guc; |
|||
}
a.A C program
4:main(){ char Isc; unsigned int lui;
0000095B 1B9D |
LEAS -3,SP |
5:Isc = Isc & guc; Isc &= 0x12;
0000095D |
A682 |
LDAA |
2, SP |
0000095F B40800 |
ANDA |
$0800 |
|
00000962 |
6A82 |
STAA |
2,SP |
00000964 |
OD82ED |
BCLR |
2,SPf#237 |
6:gsi = gsi|lui; gsi = gsi|0x1234;
00000967 |
FC0801 |
LDD |
$0801 |
0000096A |
EA81 |
GRAB |
1,SP |
0000096C AA80 |
ORAA |
0,SP |
|
0000096E |
7C0801 |
STD |
$0801 |
00000971 |
1C080112 |
BSET |
$0801,#18 |
00000975 |
1C080234 |
BSET |
$0802,#52 |
7:lui = Isc *guc;
00000979 |
A682 |
LDAA |
2,SP |
0000097B B706 |
SEX |
ArY |
|
0000097D |
F60800 |
LDAB |
$0800 |
00000980 |
87 |
CLRA |
|
00000981 |
13 |
EMUL |
|
00000982 |
6C80 |
STD |
0,SP |
7:lui = lui / guc;
00000984 F60800 |
LDAB |
$0800 |
|
00000987 |
87 |
CLRA |
|
00000988 |
B745 |
TFR |
D,X |
0000098A ECB1 |
LDD |
0,SP |
|
0000098C |
1810 |
IDIV |
|
0000098E |
6E80 |
STX |
0,SP |
8: } |
|||
00000990 |
1B83 |
LEAS |
3,SP |
00000992 |
3D |
RTS |
|
b. Assembly Language Generated by Part (a)
Figure 93. A C Program with SomeOperators
However, if one of the operands is constant, BSET can be used. The expression gsi =
gsi | 0x1234; orequivalently gsi |
|= 0x1234; isrealizedby |
|
BSET |
$0801,#18 |
;OR high byte of global variable gsi with Ox 12 |
BSET |
$0802, #52 |
; OR global variable low byte gsi with 0x34 |
262 |
Chapter 9 Implementation of C Procedures |
|
LDX |
$0801 |
;getgsi |
INX |
; add 1 |
|
STX |
$0801 |
; put it back |
and the statement lui—; in Figure 9.4 is implemented |
||
LDX |
1, SP |
; get lui |
DEX |
; subtract 1 |
|
STX |
1, SP |
; put it back |
When the increment or decrement operator appears in a larger expression, the initial or final value of the variable used in the outer expression depends on whether the pair of "+" or "-" signs appearsbefore or after the variable. Isc = ++ guc; is implemented
unsigned char guc; int gsi; main{){ char Isc; unsigned int lui;
guc++; Isc—; gsi++; lui—; Isc = ++guc; Isc = guc++;
}
a.A C Program
4:main(){ char Isc; unsigned int lui;
0000095B 1B9D |
LEAS -3,SP |
5:guc++;
0000095D |
720800 |
INC |
$0800 |
6: |
Isc—; |
||
00000960 |
6380 |
DEC |
0,SP |
7:gsi++;
00000962 |
FE0801 |
LDX |
$0801 |
00000965 |
08 |
INX |
|
00000966 |
7E0801 |
STX |
$0801 |
8:lui—;
00000969 |
EE81 |
LDX |
1,SP |
0000096B 09 |
DEX |
||
0000096C |
6E81 |
STX |
1,SP |
9:Isc = ++guc;
0000096E |
720800 |
INC |
$0800 |
00000971 |
B60800 |
LDAA |
$0800 |
00000974 |
6A80 |
STAA |
0,SP |
10:Isc = guc++;
00000976 |
A680 |
LDAA |
0,SP |
00000978 |
720800 |
INC |
$0800 |
0000097B |
6A80 |
STAA |
OrSP |
0000097D |
1B83 |
LEAS |
3,SP |
0000097F |
3D |
RTS |
b. Assembly Language Generatedby Part (a)
Figure 9.4. A C Program with Incrementing andDecrementing
264 |
Chapter 9 Implementation of C Procedures |
unsigned char guc; int gsi;
main(){ char Isc; unsigned |
int lui; |
|
lui |
-= Isc; lui = (lui |
& Oxfc7f) j ((Isc « 7) & 0x380); |
lui |
= (lui « 3) + (lui |
« 1) + Isc - '0' ; |
}
a.C Program
4:main(){ char Isc; unsigned int lui; lui -= Isc;
0000095B |
1B9D |
LEAS |
-3,SP |
0000095D A682 |
LDAA |
2,SP |
|
0000095F B706 |
SEX |
A,Y |
|
00000961 EC80 |
LDD |
0,SP |
|
00000963 |
35 |
PSHY |
|
00000964 |
A3B1 |
SUBD |
2,SP+ |
00000966 |
6C80 |
STD |
0,SP |
6: |
lui = (lui |
& Oxfc7f)| |
((Isc « 7) & 0x380); |
00000968 |
3B |
PSHD |
|
00000969 C680 |
LDAB |
#128 |
|
0000096B |
87 |
CLRA |
|
0000096C |
35 |
PSHY |
|
0000096D |
13 |
EMUL |
|
0000096E C480 |
ANDB |
#128 |
|
00000970 |
8403 |
ANDA |
#3 |
00000972 |
3B |
PSHD |
|
00000973 |
EC84 |
LDD |
4,SP |
00000975 |
C47F |
ANDB |
#127 |
00000977 |
84FC |
ANDA |
#252 |
00000979 |
AA81 |
ORAA |
1,SP+ |
0000097B |
EA81 |
GRAB |
0,SP+ |
0000097D |
6C82 |
STD |
2,SP |
7:lui = (lui « 3) + (lui « 1) + Isc -'0 ' ;
0000097F |
59 |
ASLD |
|
00000980 |
59 |
ASLD |
|
00000981 |
59 |
ASLD |
|
00000982 |
B745 |
TFR |
D,X |
00000984 |
EC82 |
LDD |
2,SP |
00000986 |
59 |
ASLD |
|
00000987 |
1AE6 |
LEAX |
D,X |
00000989 |
B754 |
TFR |
X,D |
0000098B |
E380 |
ADDD |
0,SP |
0000098D |
830030 |
SUBD |
#48 |
00000990 |
6C84 |
STD |
4,SP |
00000992 |
1B87 |
LEAS |
7,SP |
00000994 |
3D |
RTS |
b. Assembly Language Generatedby Part (a)
Figure 9.5. A C Program with ORing, ANDing and Shifting
266 |
Chapter 9 Implementation of C Procedures |
unsigned char guc; int gsi; |
|||||
main{){ |
char |
Isc; unsigned int lui; |
|||
guc |
= Isc |
> -3; |
Isc = lui > 5; lui |
= gsi |
>= 0; |
gsi |
= lui |
>= 0; |
gsi = Isc — 0; |
Isc = |
(gsi & 4) == 0; |
1
a.A C Program
5:guc = Isc > -3; Isc = lui > 5;
0000095B A6AD |
LDAA |
3,-SP |
||
0000095D |
81FD |
CMPA |
#253 |
|
0000095F |
2E02 |
BGT |
*+4 |
;abs = 0963 |
00000961 |
87 |
CLRA |
||
00000962 |
8F8601 |
CPS |
#34305 |
|
00000965 |
7A0800 |
STAA |
$0800 |
|
00000968 |
EC81 |
LDD |
1,SP |
|
0000096A |
8C0005 |
CPD |
#5 |
|
0000096D |
2202 |
BHI |
*+4 |
;abs = 0971 |
0000096F |
87 |
CLRA |
||
00000970 |
8F8601 |
CPS |
#34305 |
|
00000973 |
6A80 |
STAA |
0,SP |
|
7:lui = gsi >= 0;
00000975 |
FC0801 |
LDD |
$0801 |
|
00000978 2A02 |
BPL |
*+4 |
;abs = 097C |
|
0000097A |
C7 |
CLRB |
||
0000097B |
8FC601 |
CPS |
#50689 |
|
0000097E |
87 |
CLRA |
||
0000097F |
6C81 |
STD |
1,SP |
|
8s |
gsi = lui >= 0; |
|||
00000981 |
C601 |
LDAB |
#1 |
|
00000983 |
87 |
CLRA |
||
00000984 |
7C0801 |
STD |
$0801 |
|
9:gsi = Isc == 0;
00000987 A680 |
LDAA |
0,SP |
||
00000989 |
2702 |
BEQ |
*+4 |
,-abs = 098D |
0000098B |
C7 |
CLRB |
||
0000098C |
8FC601 |
CPS |
#50689 |
|
0000098F |
87 |
CLRA |
||
00000990 |
7C0801 |
STD |
$0801 |
|
10:Isc = (gsi& 4) == 0;
00000993 |
1F08020402 |
BRCLR |
$0802,#4,*+7 |
;abs = 099A |
00000998 |
87 |
CLRA |
||
00000999 |
8F8601 |
CPS |
#34305 |
|
0000099C 6AB2 |
STAA |
3,SP+ |
||
b. Assembly Language Generated by the body of Part (a)
Figure 9.6. A Program with Boolean Operators
268 |
Chapter 9 Implementation of C Procedures |
||
Certain bit tests can often use BRSET |
or BRCLR branches. In Figure 9.6, the |
||
expression Isc = (gsi & 4) |
== 0; results in the following code: |
||
BRCLR |
$0802, #4 , *+2 |
;if bit 4 is not zero then |
|
CLRA |
; clear result |
||
GPS |
#34305 |
; skip, or set result to 1 |
|
STAA |
3, SP+ |
; put result in lui and deallocate local variables |
|
The Boolean result of the test, a value of 1 (T) or a 0 (F), is actually not usually generated but may be used to branch to a different location. For instance if {lui > 5) results in the following code:
LDD |
1, SP |
; get 16-bit variable lui |
CPD |
#5 |
; if less than 5 as an unsigned number |
BLS |
L |
; branch around the expression if lui is higher than 5 |
Simple conditional expressions of the form if then, full conditionals of the form if then else, and extended conditionals of the form if then else if then else if then , . . else, use conditional expression operators. In the last expression, the else if part can be repeated as many times as needed, and the last part can be an optional else. Variables are compared using relational operators ( > and < ), and these are combined using logical operators (&&). We give examples of common simple conditionals first.
The C program in Figure 9.7a is compiled into the assembly language program shown in Figure 9.7b. A statement if (! Isc) guc = 0; or equivalently if (Isc ==
0) guc = 0; is encoded as |
||
LDAA |
3, -SP |
; allocate and set condition codes for variable Isc |
BNE |
*+5 |
; if nonzero, skip over next instruction |
CLR |
$0800 |
;otherwise, if zero, clear variable guc |
Where the condition applies to a complex expression of many statements, the branch instructions can be converted to long branch instructions. For instance,
if (gsi |
< 5) { ... /* many instructions */} |
||
can be implemented |
|||
LDD |
$0801 |
;get variable gsi |
|
CPD |
#5 |
; if greater than or equal to 5 as an unsigned number |
|
LBGE |
LI |
; then skip over next several instructions |
|
; many instructions generated between { } appear here |
|||
LI: |
EQU |
* |
; located after the latter} matching the if statement's { |
A simple C compiler can always implement the conditional operation using the long branch instructions like LBHS, but an optimizing C compiler will get the size of the branch offset. It uses a long branch instruction when the label cannot be reached by the corresponding shorter branch instruction.