Page 290 - Introduction to Microcontrollers Architecture, Programming, and Interfacing of The Motorola 68HC12
P. 290
9.3 Conditional Statements 267
Note that signed numbers use branches like BGT. Unsigned number comparisons use
branches like BHI, One of the more difficult problems of accurately translating C into
assembly language is that of choosing the correct kind of conditional branch instruction
to take care of signed or unsigned comparisons.
In one of the more peculiar operations, CPS #34305 is used to skip a two-byte
operand, LDAA #1. Suppose the instruction is at location $962. If the entire
instruction is executed, the only effect is that the condition codes are set, but they are not
tested in subsequent instructions, so the CPS #34305 is a no-op. However, if a branch
to $963 is made, the constant 34305 is executed as an opcode. This instruction is LDAA
#1, and the result is to load 1 into accumulator A. The HiWare C compiler uses this
technique to make accumulator A either a 1 (T) or a 0 (F). We see several examples in
the program in Figure 9.6. It is also used in a case statement in which several of the
cases load different values into the same variable. Such a case statement appears in
Figure 9.9.
The expression Isc = lui > 5; in Figure 9.6 results in the following code:
LDD 1, SP ; get 16-bit variable lui
CPD #5 ; if less than 5 as an unsigned number
BHI *+4 ; branch to the operand of the CPS instruction
CLRA ; otherwise clear the value
CPS #34305 ; skip, or else set result to 1.
STAA 0, SP ; store the result
Note that the constant 1 (T) or a 0 (F) is generated in accumulator A to reflect the
Boolean value of the test lui > 5. Signed number comparisons that test just the sign
use branches like BPL. The expression lui = gsi >= 0 j in Figure 9.6 results in the
following code:
LDD $0801 ; preclear result
BPL *+4 ; if nonnegative then
CLRB ; clear and skip
CPS #50689 ; skip or set result to 1.
CLRA ; high result is always 0
STD 1, SP ; put result in lui
Note that there is no test for the expression gsi = lui >= 0;, because unsigned
numbers are always nonnegative. This is an error made by many programmers. Be careful
when you determine the data type of a variable and when you test that variable, so that
you avoid the situation where you test a variable declared to be an unsigned number for a
value less than zero or a value greater or equal to zero.
Comparisons for equality or inequality can often use TST and branches like
BEQ. The expression gsi = Isc == 0; in Figure 9.6 results in the following code:
LDAA 0, SP ; test 8-bit variable Isc
BEQ *+4 ; if nonzero then
CLRB ; clear and skip
CPS #50689 ; skip or set result to 1.
CLRA ; high result is always 0
STD $0801 ; put result in gsi