Chapter 2 HCS12 Assembly Programming
Chapter 2 HCS12 Assembly Programming
Chapter 2 HCS12 Assembly Programming
You also want an ePaper? Increase the reach of your titles
YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.
<strong>Chapter</strong> 2<br />
<strong>HCS12</strong> <strong>Assembly</strong> <strong>Programming</strong>
Three Sections of a <strong>HCS12</strong>/MC9S12<br />
<strong>Assembly</strong> Program<br />
• Assembler directives<br />
– Defines data and symbol<br />
– Reserves and initializes memory locations<br />
– Sets assembler and linking condition<br />
– Specifies p output p format<br />
– Specifies the end of a program<br />
• <strong>Assembly</strong> language instructions<br />
– <strong>HCS12</strong>/MC9S12 instructions<br />
• Comments<br />
– Explains the function of a single or a group of instructions
Fields of a <strong>HCS12</strong> Instruction<br />
• Label field<br />
– Optional<br />
– Starts with a letter and<br />
ffollowed<br />
by letters, digits, or<br />
special symbols (_ or .)<br />
– Can start from any column if<br />
ended with “:”<br />
– Must start from column 1 if not<br />
ended with “:”<br />
• Operation field<br />
– Contains the mnemonic of a<br />
machine instruction or an<br />
assembler directive<br />
– Separated from the label by at<br />
least one space<br />
• Operand field<br />
– Follows the operation field and<br />
is separated p from the<br />
operation field by at least one<br />
space<br />
– Contains operands for<br />
instructions or arguments for<br />
assembler bl di directives ti<br />
• Comment field<br />
– Any line starts with an * or ; is<br />
a comment<br />
– Separated from the operand<br />
and operation field for at least<br />
one space<br />
– Optional p
Identify the Four Fields of an Instruction<br />
Example<br />
loop ADDA #$40 ; add 40 to accumulator A<br />
(1) “loop” is a label<br />
(2) “ADDA” is an instruction mnemonic<br />
(3) “#$40” #$40 is the operand<br />
(4) “add #$40 to accumulator A” is a comment<br />
movb 0,X,0,Y ; memory to memory copy<br />
(1) no label field<br />
(b) “movb” is an instruction mnemonic<br />
(c) “0,X,0,Y” is the operand field<br />
(d) “; ; memory to memory copy” copy is a comment
Assembler Directives<br />
• END<br />
– Ends a program to be processed by an assembler<br />
– Any statement following the END directive is ignored ignored.<br />
• ORG<br />
– The assembler uses a location counter to keep track of the memory<br />
location where the next machine code byte should be placed.<br />
– This directive sets a new value for the location counter of the<br />
assembler.<br />
– The sequence<br />
ORG $2000<br />
LDAB #$FF<br />
places the opcode byte for the instruction LDAB #$FF at<br />
location $2000. $
dc.b (define ( constant byte) y )<br />
db (define byte)<br />
fcb (form constant byte)<br />
- These three directives define the value of a byte or bytes that will be placed at a given<br />
location.<br />
- These directives are often preceded by the org directive.<br />
- For example,<br />
org $2000<br />
arrayy dc.b $11,$22,$33,$44<br />
dc.w (define constant word)<br />
dw (define word)<br />
fdb (form ( double bytes) y )<br />
- Define the value of a word or words that will be placed at a given location.<br />
- The value can be specified by an expression.<br />
- For example,<br />
vec_tab _<br />
dc.w $1234, abc-20
fcc (form constant character)<br />
• Used to define a string of characters (a message)<br />
• The first character (and the last character) is used as the<br />
ddelimiter. li it<br />
• The last character must be the same as the first<br />
character.<br />
• The delimiter must not appear in the string.<br />
• The space character cannot be used as the delimiter.<br />
• EEach h character h t iis represented t d bby it its ASCII code. d<br />
• Example<br />
msg fcc “Please Please enter 1, 2 or 3:” 3:
fill (fill memory)<br />
- This directive allows the user to fill a certain number of memory locations with a<br />
given value.<br />
- The syntax is fill value,count<br />
- Example<br />
space_line fill $20,40<br />
ds (define storage)<br />
rmb b( (reserve memory byte) b t )<br />
ds.b (define storage bytes)<br />
- Each of these directives reserves a number of bytes given as the arguments to the<br />
di directive. ti<br />
- Example<br />
buffer ds 100<br />
reserves 100 bytes y
ds ds.w w (define storage word)<br />
rmw (reserve memory word)<br />
- Each of these directives increments the location counter by the value indicated in<br />
the number-of-words argument multiplied by two.<br />
- Example<br />
dbuf ds.w 20<br />
reserves 40 bytes starting from the current location counter<br />
equ (equate)<br />
- This directive assigns a value to a label.<br />
- Using this directive makes one’s one s program more readable readable.<br />
- Examples<br />
arr_cnt equ 100<br />
oc_cnt equ 50
loc<br />
- This directive increments and produces an internal counter used in conjunction with<br />
the backward tick mark (`).<br />
- By using the loc directive and the ` mark mark, one can write program segments like the<br />
following example, without thinking up new labels:<br />
loc loc<br />
ldaa #2 ldaa #2<br />
loop` deca same as loop1 deca<br />
bne loop` bne loop1<br />
loc loc<br />
loop` brclr 0,x,$55,loop` loop2 brclr 0, x, $55, loop2
Macro<br />
- A name a e ass assigned g ed to a ggroup oup of o instructions st uct o s<br />
- Use macro and endm to define a macro.<br />
- Example of macro<br />
sumOf3 macro arg1,arg2,arg3<br />
g , g , g<br />
ldaa arg1<br />
adda arg2<br />
adda<br />
endm<br />
arg3<br />
- Invoke a defined macro: write down the name and the arguments of the macro<br />
sumOf3<br />
is replaced p by y<br />
$1000,$1001,$1002<br />
ldaa $1000<br />
adda $1001<br />
adda $1002
Software Development Process<br />
• Problem definition: Identify what should be done.<br />
– Develop the algorithm.<br />
• Algorithm is the overall plan for solving the problem at hand hand.<br />
• An algorithm is often expressed in the following format:<br />
– Step 1<br />
– …<br />
– Step 2<br />
– …<br />
– Another way to express overall plan is to use flowchart.<br />
• <strong>Programming</strong>. g g Convert the algorithm g or flowchart into<br />
programs.<br />
• Program testing<br />
• Program maintenance
Symbols of Flowchart<br />
Terminal<br />
Process<br />
IInput t or<br />
output B<br />
Decision<br />
no<br />
yes<br />
A<br />
on-page connector<br />
A<br />
Subroutine<br />
off-page connector<br />
Figure 2.1 Flowchart symbols used in this book
Programs to Do Simple Arithmetic (1 of 5)<br />
Example 2.4 Write a program to add the values of memory locations at $1500, $1501, and<br />
$1502, and save the result at $1510.<br />
Solution:<br />
Step 1<br />
A ⇐ m[$1500]<br />
Step 2<br />
A ⇐ A + m[$1501]<br />
Step 3<br />
A ⇐ A + m[$1502]<br />
Step 4<br />
m[$1510] ⇐ A<br />
org $2000<br />
ldaa $1500<br />
adda $1501<br />
adda $1502<br />
staa<br />
end<br />
$1510
Programs to Do Simple Arithmetic (2 of 5)<br />
Example 2.4 Write a program to subtract the contents of the memory<br />
location at $1505 from the sum of the memory locations at $1500 and<br />
$1502, and store the difference at $1510.<br />
Solution:<br />
org $2000<br />
ldaa $1500<br />
adda $1502<br />
suba $1505<br />
staa $1510<br />
end
Programs to Do Simple Arithmetic (3 of 5)<br />
Example 2.6 Write a program to add two 16-bit 16 bit numbers that are stored at<br />
$1500-$1501 and $1502-$1503 and store the sum at $1510-$1511.<br />
Solution:<br />
org og $2000 $ 000<br />
ldd $1500 ; D
Programs to Do Simple Arithmetic (4 of 5)<br />
Example 2.7 Write a program to add two 4-byte numbers that are stored at<br />
$1500-$1503 and $1504-$1507, and store the sum at $1510-$1513.<br />
Solution: Addition starts from the LSB and proceeds toward MSB.<br />
org $2000<br />
ldd $1502 ; add and save the least significant two bytes<br />
addd $1506 ; “<br />
std $1512 ; “<br />
ldaa $1501 ; add and save the second most significant bytes<br />
adca $1505 ; “<br />
staa $1511 ; “<br />
ldaa $1500 ; add and save the most significant bytes<br />
adca $1504 ; “<br />
staa<br />
end<br />
$1510 ; “
Programs to Do Simple Arithmetic (5 of 5)<br />
Example 2.8 Write a program to subtract the hex number stored at $1504-$1507<br />
from the hex number stored at $1500-$1503 and save the result at $1510-$1513.<br />
Solution: The subtraction starts from the LSBs and proceeds toward the MSBs.<br />
org $2000<br />
ldd $1502 ; subtract and save the least significant two bytes<br />
subd $1506 ; “<br />
std $1512 ; “<br />
ldaa $1501 ; subtract and save the difference of the second to most<br />
sbca $1505 ; significant bytes<br />
staa $1511 ; “<br />
ldaa $1500 ; subtract and save the difference of the most significant<br />
sbca $1504 ; bytes<br />
staa<br />
end<br />
$1510 ; “
Multiplication and Division (1 of 2)<br />
Table 2.1 Summary of <strong>HCS12</strong> multiply and divide instructions<br />
Mnemonic Function<br />
Operation<br />
emul unsigned 16 by 16 multiply (D) × (Y) → Y:D<br />
emuls signed 16 by 16 multiply<br />
(D) × (Y) → Y:D<br />
mul unsigned 8 by 8 multiply (A) × (B) → A:B<br />
(Y:D) ÷ (X)<br />
ediv unsigned 32 by 16 divide quotient → Y<br />
remainder → D<br />
(Y (Y:D) D)÷(X) ÷ (X)<br />
edivs signed 32 by 16 divide quotient → Y<br />
remainder → D<br />
fdiv 16 by 16 fractional divide (D) ÷ (X) → X<br />
remainder → D<br />
idiv unsigned 16 by 16 integer<br />
(D)÷ (D) ÷ (X) → X<br />
divide<br />
remainder → D<br />
idivs signed 16 by 16 integer (D) ÷ (X) → X<br />
divide<br />
remainder → D
Program Loops<br />
• Types of program loops: finite and infinite loops<br />
• Looping mechanisms:<br />
– do statement S forever<br />
– For i = n1 to n2 do statement S or For i = n2 down to n1 do<br />
statement S<br />
– Whil While C ddo statement t t t S<br />
– Repeat statement S until C<br />
• Program loops are implemented by using the conditional<br />
branch instructions and the execution of these<br />
instructions depends on the contents of the CCR<br />
register.
I ← i 1<br />
I ≤ i 2 ?<br />
S<br />
S<br />
Figure 2.4 An infinite loop<br />
yes<br />
I ← I + 1<br />
no<br />
I ← i 2<br />
I ≥ i 1 ?<br />
S<br />
yes<br />
I ← I - 1<br />
no<br />
true<br />
C S<br />
false<br />
Figure 2.6 The While ... Do looping construct<br />
initialize C<br />
(a) For I = i 1 to i 2 DO S (b) For I = i 2 downto i 1 DO S Figure 2.7 The Repeat ... Until looping construct<br />
Figure 2.5 For looping construct<br />
S<br />
C<br />
false<br />
true
Condition Code Register<br />
7 6 5 4 3 2 1 0<br />
S X H I N Z V C<br />
Figure 2.8 Condition code register<br />
• Four types of branch instructions<br />
– Unary (unconditional) branch: always execute<br />
– Simple branches: branch is taken when a specific bit of CCR is in a<br />
specific status<br />
– Unsigned branches: branches are taken when a comparison or test of<br />
unsigned numbers results in a specific combination of CCR bits<br />
– Signed branches: branches are taken when a comparison or test of<br />
signed quantities are in a specific combination of CCR bits<br />
• Two categories of branches<br />
– Short branches: in the range of -128 ~ +127 bytes<br />
– Long branches: in the range of 64KB
Condition Code Register<br />
• C: the carry flag. flag C=1, C=1 implies a carry is generated generated.<br />
• V: the overflow flag. V=1, implies the result of a 2’s<br />
complement arithmetic operation is out of range.<br />
• Z: the zero flag. Z=1, the result of an operation is zero.<br />
• N: the negative flag. N=1, the most significant bit of the<br />
result of an operation is 1.<br />
• H: the half-carry flag. H=1, there is a carry from the lower<br />
four bits to the upper four bits as the result of an<br />
operation operation.
Mnemonic<br />
Table 2.2 Summary of short branch instructions<br />
Function<br />
Unary Branches<br />
BRA Branch always<br />
BRN Branch never<br />
Simple Branches<br />
Mnemonic Function<br />
BCC Branch if carry clear<br />
BCS Branch if carry set<br />
BEQ Branch if equal<br />
BMI Branch if minus<br />
BNE Branch if not equal<br />
BPL Branch if plus<br />
BVC Branch if overflow clear<br />
BVS Branch if overflow set<br />
Unsigned Branches<br />
Mnemonic Function<br />
BHI<br />
BHS<br />
BLO<br />
BLS<br />
Branch if higher<br />
BBranch h if higher hi h or same<br />
Branch if lower<br />
Branch if lower or same<br />
Signed Branches<br />
Equation or Operation<br />
1 = 1<br />
1 = 0<br />
Equation or Operation<br />
C = 0<br />
C = 1<br />
Z = 1<br />
N = 1<br />
Z = 0<br />
N = 0<br />
V = 0<br />
V = 1<br />
Equation or Operation<br />
C + Z = 0<br />
C = 0<br />
C = 1<br />
C + Z = 1<br />
Mnemonic Function Equation q or Operation p<br />
BGE<br />
BGT<br />
BLE<br />
BLT<br />
Branch if greater than or equal<br />
Branch if greater than<br />
Branch if less than or equal<br />
Branch if less than<br />
N ⊕ V = 0<br />
Z + (N ⊕ V) = 0<br />
Z + (N ⊕ V) = 1<br />
N ⊕ V = 1
Mnemonic<br />
Table 2.3 Summary of long branch instructions<br />
Function<br />
Unary Branches<br />
LBRA Long branch always<br />
LBRN Long branch never<br />
Simple Branches<br />
Mnemonic Function<br />
LBCC Long branch if carry clear<br />
LBCS<br />
LBEQ<br />
LBMI<br />
LBNE<br />
LBPL<br />
LBVC<br />
LBVS<br />
Long branch if carry set<br />
Long branch if equal<br />
Long branch if minus<br />
Long branch if not equal<br />
Long branch if plus<br />
Long branch if overflow overflowis is clear<br />
Long branch if overflow set<br />
Unsigned Branches<br />
Mnemonic Function<br />
LBHI Long branch if higher<br />
LBHS<br />
LBLO<br />
LBLS<br />
Long branch if higher or same<br />
Long branch if lower<br />
Long branch if lower or same<br />
Signed Branches<br />
Equation or Operation<br />
1 = 1<br />
1 = 0<br />
Equation or Operation<br />
C = 0<br />
C = 1<br />
Z = 1<br />
N = 1<br />
Z = 0<br />
N = 0<br />
V=0 V = 0<br />
V = 1<br />
Equation or Operation<br />
C + Z = 0<br />
C = 0<br />
C = 1<br />
C + Z = 1<br />
Mnemonic Function Equation or Operation<br />
LBGE<br />
LBGT<br />
LBLE<br />
LBLT<br />
Long branch if greater than or equal<br />
Long branch if greater than<br />
Long branch if less than or equal<br />
Long branch if less than<br />
N ⊕ V = 0<br />
Z + (N ⊕ V) = 0<br />
Z + (N ⊕ V) = 1<br />
N ⊕ V = 1
Compare and Test Instructions<br />
• Condition flags need to be set up before conditional branch<br />
instruction should be executed.<br />
• The <strong>HCS12</strong> provides a group of instructions for testing the condition<br />
flags flags.<br />
Table 2.4 Summary yof compare p and test instructions<br />
Mnemonic Function<br />
CBA Compare A to B<br />
CMPA<br />
CMPB<br />
CPD<br />
CPS<br />
CPX<br />
CPY<br />
Compare A to memory<br />
Compare B to memory<br />
Compare D to memory<br />
Compare SP to memory<br />
Compare X to memory<br />
Compare Y to memory<br />
Compare instructions<br />
Test instructions<br />
Operation<br />
(A) - (B)<br />
(A) - (M)<br />
(B) - (M)<br />
(D) - (M:M+1)<br />
(SP) - (M:M+1)<br />
(X) - (M:M+1)<br />
(Y) - (M:M+1)<br />
Mnemonic Function Operation<br />
TST<br />
TSTA<br />
TSTB<br />
Test memory for zero or minus<br />
Test A for zero or minus<br />
Test B for zero or minus<br />
(M) - $00<br />
(A) - $00<br />
(B) - $00
• <strong>HCS12</strong> provides<br />
a group of<br />
instructions that<br />
either decrement<br />
or increment a<br />
loop count to<br />
ddetermine t i if th the<br />
looping should be<br />
continued.<br />
• The range of the<br />
branch is from<br />
$80 (-128) to $7F<br />
(+127).<br />
Loop Primitive Instructions<br />
Table 2.5 2 5 Summary of loop primitive instructions<br />
Mnemonic Function<br />
DBEQ cntr, rel<br />
DBNE cntr, rel<br />
IBEQ cntr, rel<br />
IBNE cntr, rel<br />
• The range of the TBEQ cntr, rel<br />
TBNE cntr, rel<br />
Decrement counter and branch if = 0<br />
(counter = A, B, D, X, Y, or SP)<br />
Decrement counter and branch if ≠ 0<br />
(counter = A, B, D, X, Y, or SP)<br />
Increment counter and branch if = 0<br />
(counter = A, B, D, X, Y, or SP)<br />
Increment counter and branch if ≠ 0<br />
(counter = A, B, D, X, Y, or SP)<br />
Test counter and branch if = 0<br />
(counter = A, B, D, X, Y, or SP)<br />
Test counter and branch if ≠ 0<br />
(counter = A, B, D, X, Y, or SP)<br />
Equation or Operation<br />
counter ← (counter) - 1<br />
If (counter) = 0, then branch<br />
else continue to next instruction<br />
counter ← (counter) - 1<br />
If (counter) ≠ 0, then branch<br />
else continue to next instruction<br />
counter ← (counter) + 1<br />
If (counter) = 0, then branch<br />
else continue to next instruction<br />
counter ← (counter) + 1<br />
If (counter) ≠ 0, then branch<br />
else continue to next instruction<br />
If (counter) = 0, then branch<br />
else continue to next instruction<br />
If (counter) ≠ 0, then branch<br />
else continue to next instruction<br />
NNote. 11. cntr t iis the h loop l counter and dcan be b accumulator l A, A B, B or D and dregister i X, X Y, Y or SP. SP<br />
2. rel is the relative branch offset and is usually a label
Implementation of Looping Constructs<br />
ffor i = n1 1tto n2 2ddo S<br />
n1 equ xx ; starting index<br />
n2 equ yy ; ending index<br />
…<br />
i ds.b 1 ; loop index variable<br />
…<br />
movb #n1,i ; initialize i to n1<br />
loopf ldaa i ; check index i<br />
cmpa #n2<br />
bgt next ; if i is greater than n2, exit the loop<br />
… ; performs loop operations<br />
… ; “<br />
inc i ; increment loop index<br />
bra loopf<br />
next …
for i = n2 downto n1 do S<br />
n1 equ xx ; starting index<br />
n2 equ<br />
…<br />
yy ; ending index<br />
i ds ds.b b 1 ; loop index variable<br />
…<br />
movb #n2,i ; initialize i to n1<br />
loopf ldaa i ; check index i<br />
cmpa #n2<br />
blt next ; if i is greater than n2, exit the loop<br />
… ; perform loop operations<br />
… ; “<br />
dec i ; increment loop index<br />
bra loopf<br />
next …
While loop<br />
� Loop terminating condition is checked at the start of the loop<br />
� In the following example, icount == 0 is the condition to be check.<br />
� The update of icount is done by an interrupt service routine (not shown below).<br />
N equ<br />
…<br />
xx<br />
icount ds.b<br />
…<br />
1<br />
movb #N,icount<br />
wloop ldaa #0<br />
cmpa icount<br />
beq next<br />
…<br />
…<br />
bra wloop<br />
next …
While loop<br />
�� Loop terminating condition is checked at the start of the loop<br />
� In the following example, icount == 0 is the condition to be check.<br />
� The update of icount is done by an interrupt service routine (not shown below).<br />
N equ<br />
…<br />
xx<br />
icount ds.b<br />
…<br />
1<br />
movb #N #N,icount icount<br />
wloop ldaa #0<br />
cmpa icount<br />
beq next<br />
…<br />
…<br />
bra wloop<br />
next …
Example 2.14 Write a program to add an array of N 8-bit numbers and store the<br />
sum at memory locations $1500~$1501. Use the For i = n1 to n2 do looping<br />
construct.<br />
Solution:<br />
N equ 20<br />
org $1500<br />
sum rmb 2 ;sum is @ $1500:$1501<br />
i rmb 1 ;i is @ $1502<br />
org $2000<br />
movb #0, i ; i ← 0<br />
movw #0, sum ; sum ← 0<br />
lloop ld ldab b i ; B = i<br />
cmpb #N ; is i = N?<br />
beq done ; if equal, branch to done<br />
ldx #array ; X = address of array<br />
abx ; X = B + X, , array y pointer p<br />
ldab 0,X ; B = [x]=array(i)<br />
ldy sum ; Y = sum<br />
aby ; sum = array(i) + sum<br />
sty sum ; sum = Y, the new sum<br />
Start<br />
i ← 0<br />
sum ← 0<br />
yes<br />
i = N?<br />
Stop<br />
no<br />
sum ← sum + array[i]<br />
i ← i + 1<br />
Figure 2.9 Logic flow of example 2.14
inc i ; increment the loop count by 1<br />
bra loop ; branch back to loop<br />
done swi ; software interrupt<br />
array dc dc.b b<br />
end<br />
1234567891011121314151617181920<br />
1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20<br />
Example 2.15 Write a program to find the maximum element from an array of N 8-<br />
bit elements using the repeat S until C looping construct. construct<br />
Solution:
no<br />
Start<br />
max_val ← array[0]<br />
i ← N-1<br />
max_val < array[i] ?<br />
yes<br />
max max_val val ← array[i]<br />
i ← i - 1<br />
i = 0?<br />
Stop<br />
yes<br />
Figure 2.10 Logic flow of example 2.15<br />
no
N equ 20<br />
org $1500<br />
max max_val val ds ds.b b 1<br />
org $2000<br />
ldaa array ; set array[0] as the temporary max max<br />
staa max_val ; “<br />
ldx #array+N-1 #array N 1 ; start from the end of the array<br />
ldab #N-1 ; set loop count to N - 1<br />
loop ldaa max_val<br />
cmpa 0,x<br />
bge chk chk_end end<br />
ldaa 0,x<br />
staa max_val<br />
chk_end dex<br />
dbne b,loop ; finish all the comparison yet?<br />
forever bra forever<br />
array db 1,3,5,6,19,41,53,28,13,42,76,14<br />
db<br />
end<br />
20,54,64,74,29,33,41,45
Example 2.14 Write a program to add an array of N 8-bit numbers and store the sum<br />
at memory locations $1500~$1501. Use the For i = n2 to n1 do looping construct.<br />
SSolution: l ti<br />
N equ 20 ; N=20<br />
org $1500<br />
sum ds ds.b b 2 ;sum is @ $1500:$1501<br />
i ds.b 1 ;i is @ $1502<br />
org $2000<br />
movb #N, i ; i ← N<br />
movw #0,sum ; sum ← 0<br />
ld ldab b #N #N−1 1 ; B = N −1 1 or 19<br />
ldx #array ; X = address of array(1)<br />
loop abx ; X = B + addr. of array(1)<br />
ldab 0,X ; B ← [array(i)]<br />
ldyy sum ; Y = sum<br />
aby ; sum=array(i)+sum<br />
sty sum ; refresh sum to Y<br />
dbne b,loop ; i = I−1, branch if B ≠ 0<br />
done swi ; software interrupt<br />
array dc dc.b b 123456789101112131415<br />
1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,<br />
dc.b<br />
end<br />
16,17,18,19,20
Bit Condition Branch Instructions<br />
[] brclr (opr) , (msk),(rel) []<br />
[] brset (opr) , (msk),(rel) []<br />
where<br />
opr specifies the memory location to be checked and must be specified using<br />
either the direct, extended, or index addressing mode.<br />
msk is an 8-bit mask that specifies the bits of the memory location to be checked.<br />
The bits of the memory byte to be checked correspond to those bit positions<br />
that are 1s in the mask.<br />
rel is the branch offset and is specified in the 8-bit relative mode.<br />
For example, in the sequence<br />
loop inc count<br />
…<br />
brset $66,$E0,loop<br />
…<br />
the branch will be taken if f the most significant f three bits at $66 $ are all ones.
Example 2.17 Write a program to compute the number of elements that are<br />
divisible by 4 in an array of N 8-bit elements. Use the repeat S until C looping<br />
construct. t t<br />
Solution: A number divisible by 4 would have the least significant two bits equal 0s.<br />
N equ 20<br />
org $1500<br />
total ds.b 1<br />
org $2000<br />
clr total ; initialize total to 0<br />
ld ldx # #array ; lload d th the starting t ti address dd of f array tto RReg. X<br />
ldab #N ; use B as the loop count<br />
loop brclr 0,x,$03,yes ; if bit-1 & 0 are 0s then branch to yes<br />
bra chkend ; if the above condition is not met, branch to chkend<br />
yes iinc ttotal t l ; iincrement t the th total t t l counter t<br />
chkend inx ; increment the Reg. X, so it points to the next addr.<br />
dbne b,loop<br />
forever bra forever<br />
array db<br />
end<br />
23481213192433322018535280829094100102<br />
2,3,4,8,12,13,19,24,33,32,20,18,53,52,80,82,90,94,100,102
Instructions for Variable Initialization<br />
• [] CLR opr []<br />
where opr is specified using the extended or index<br />
addressing modes. The specified memory location is<br />
cleared.<br />
• [] CLRA []<br />
Accumulator A is cleared to 0<br />
• [] CLRB []<br />
Accumulator B is cleared to 0
Shift and Rotate Instructions<br />
The <strong>HCS12</strong> has shift and rotate instructions that apply to a memory<br />
location, accumulators A, B, and D. A memory operand must be<br />
specified using the extended or index addressing modes modes.<br />
There are three 8-bit arithmetic shift left instructions:<br />
[] asl opr [] -- memory location opr is shifted left one place<br />
[] asla [] -- accumulator A is shifted left one place<br />
[] aslb [] -- accumulator B is shifted left one place<br />
The operation is<br />
C<br />
b7 ----------------- b0<br />
0
The <strong>HCS12</strong> has one 16-bit arithmetic shift left instruction:<br />
[] asld []<br />
The operation is<br />
C b7 ----------------- b0 b7 ----------------- b0 0<br />
accumulator A accumulator B<br />
The <strong>HCS12</strong> has arithmetic shift right g instructions that apply ppy to a memory y location<br />
and accumulators A and B.<br />
[] asr opr [] -- memory location opr is shifted right one place<br />
[] asra [] -- accumulator A is shifted right one place<br />
[] asrb [] -- accumulator B is shifted right one place<br />
The operation is<br />
b7 ----------------- b0<br />
C
The <strong>HCS12</strong> has logical shift left instructions that apply to a memory<br />
location and accumulators A and BB.<br />
[] lsl opr [] -- memory location opr is shifted left one place<br />
[] lsla [] -- accumulator A is shifted left one place<br />
[] [ label ] lslb [] [ comment ] -- accumulator B is shifted left one place<br />
The operation is<br />
C b7 ----------------- b0 0<br />
The <strong>HCS12</strong> has one 16-bit logical shift left instruction:<br />
[] lsld []<br />
The operation is<br />
C b7 ----------------- b0 b7 ----------------- b0 0<br />
accumulator A<br />
accumulator B
The <strong>HCS12</strong> has three logical shift right instructions that apply to 8-bit<br />
operands operands.<br />
[] lsr opr [] -- memory location opr is shifted right one place<br />
[] lsra [] -- accumulator A is shifted right one place<br />
[] [ label ] lsrb [] [ comment ] -- accumulator B is shifted right one place<br />
The operation is<br />
0<br />
b7 ----------------- b0<br />
The <strong>HCS12</strong> has one 16-bit logical shift right instruction:<br />
[] lsrd []<br />
The operation is<br />
0 b7 ----------------- b0 b7 ----------------- b0<br />
accumulator A<br />
C<br />
accumulator B<br />
C
The <strong>HCS12</strong> has three rotate left instructions that operate on 9-bit<br />
operands.<br />
[] rol opr<br />
place<br />
[] -- memory location opr is rotated left one<br />
[] [ ] rola [] [ ] -- accumulator A is rotated left one place p<br />
[] rolb [] -- accumulator B is rotated left one place<br />
The operation is<br />
b7 ----------------- b0<br />
The <strong>HCS12</strong> has three rotate right instructions that operate on 9-bit<br />
operands.<br />
[] [ ] ror opr p<br />
place<br />
[] [ ] -- memory y location opr p is rotated right g one<br />
[] rora [] -- accumulator A is rotated right one place<br />
[] rorb [] -- accumulator B is rotated right one place<br />
The operation is<br />
C b7 ----------------- b0<br />
C
Example 2.18 Suppose that [A] = $95 and C = 1. Compute the new values of<br />
A and C after the execution of the instruction asla asla.<br />
Solution:<br />
accumulator A<br />
C flag<br />
1 0 0 1 0 1 0 1<br />
1 0 0 1 0 1 0 1 0<br />
Figure 2.11a Operation of the ASLA instruction<br />
0<br />
Original value New value<br />
[A] = 10010101 [A] = 00101010<br />
C = 1<br />
C = 1<br />
Figure 2.11b Execution result of the ASLA instruction<br />
Example 219 2.19 S Suppose that m[$800] $800 = $ $ED and C = 00. CCompute<br />
the new<br />
values of m[$800] and the C flag after the execution of the instruction asr<br />
$1000.<br />
Solution:<br />
memory location<br />
$1000<br />
1 1 1 0 1 1 0 1<br />
1 1 1 1 0 1 1 0<br />
1<br />
C flag<br />
Original value New value<br />
[$1000] = 11101101<br />
C = 0<br />
[$1000] = 11110110<br />
C = 1<br />
Figure 2.12a Operation of the ASR $1000 instruction Figure 2.12b Result of the asr $1000 instruction
Example 2.20 Suppose that m[$1000] = $E7 and C = 1. Compute the new<br />
contents of m[$1000] and the C flag after the execution of the instruction lsr<br />
$1000 $1000.<br />
Solution: 1 1 1 0 0 1 1 1<br />
memory<br />
location<br />
$800<br />
0<br />
0 1 1 1 0 0 1 1<br />
Figure 2.13a Operation of the LSR $800 instruction<br />
1<br />
C flag Original value New value<br />
[$800] = 11100111<br />
[$800] = 01110011<br />
C = 1<br />
C = 1<br />
Figure 2.13b Execution result of LSR $800<br />
EExample l 2.21 2 21 SSuppose that h [B] = $BD and d C = 11. CCompute the h new values l of f<br />
B and the C flag after the execution of the instruction rolb.<br />
Solution:<br />
accumulator B<br />
1 0 1 1 1 1 0 1<br />
0 1 1 1 1 0 1 1 1<br />
Figure 2.14a Operation of the instruction ROLB<br />
1<br />
C flag<br />
Original value New value<br />
[B] = 10111101<br />
C = 1<br />
[B] = 01111011<br />
C = 1<br />
Figure 14b. Execution result of ROLB
Example 2.22 Suppose that [A] = $BE and C = 1. Compute the new<br />
values l of f mem[$00] [$00] after ft the th execution ti of f the th instruction i t ti rora.<br />
Solution:<br />
C flag<br />
1 1 0 1 1 1 1 1 0<br />
0 1 1 0 1 1 1 1 1 accumulator A<br />
Figure 2.15a Operation of the instruction rora<br />
Original value New value<br />
[A] = 10111110<br />
C = 1<br />
[A] = 11011111<br />
C = 0<br />
Figure 2.15b Execution result of rora
Example 2.23 Write a program to count the number of 0s in the 16-bit<br />
number stored at $1500-$1501 and save the result in $1505.<br />
Solution:<br />
* The 16-bit number is shifted to the right 16 time.<br />
* If the bit shifted out is a 0 then increment the 0s count by 1.<br />
org $1500<br />
db $23 $23,$55 $55 ; test data<br />
org $1505<br />
zero_cnt rmb 1<br />
lp_cnt rmb 1<br />
org $2000<br />
clr zero_cnt ; initialize the 0s count to 0<br />
ldaa #16<br />
staa lp_cnt<br />
ldd $1500 ; place the number in D<br />
loop lsrd ; shift the lsb of D to the C flag<br />
bcs chkend ; is the C flag a 0?<br />
inc zero_cnt ; increment 1s count if the lsb is a 1<br />
chkend dec lp lp_cnt cnt ; check to see if D is already 0<br />
bne loop<br />
forever bra<br />
end<br />
forever
Shift a Multi-byte Number (1 of 4)<br />
• For shifting right<br />
– The bit 7 of each byte will receive the bit 0 of its immediate left<br />
byte with the exception of the most significant byte which will<br />
receive a 0.<br />
– Each byte will be shifted to the right by 1 bit. The bit 0 of the<br />
least significant g byte y will be lost.<br />
• Suppose there is a k-byte number that is stored at loc to<br />
loc+k-1.<br />
– Method for shifting right<br />
• Step 1: Shift the byte at loc to the right one place.<br />
• Step 2: Rotate the byte at loc+1 to the right one place.<br />
• Step 3: Repeat Step 2 for the remaining bytes.
Shift a Multi-byte Number (2 of 4)<br />
• For shifting left<br />
– The bit 0 of each byte will receive the bit 7 of its immediate right<br />
byte with the exception of the least significant byte which will<br />
receive a 0.<br />
– Each byte will be shifted to the left by 1 bit. The bit 7 of the most<br />
significant g byte y will be lost.<br />
• Suppose there is a k-byte number that is stored at loc to<br />
loc+k-1.<br />
– Method for shifting left<br />
• Step 1: Shift the byte at loc+k-1 to the left one place.<br />
• Step 2: Rotate the byte at loc+K-2 to the left one place.<br />
• Step 3: Repeat Step 2 for the remaining bytes.
Shift a Multi-byte Number (3 of 4)<br />
Example 2.24 Write a program to shift the 32-bit number stored at<br />
$1520-$1523 to the right four places.<br />
Solution:<br />
ldab #4 ; set up the loop count<br />
ldx #$1520 ; use X as the pointer to the left most byte<br />
again lsr 0,X ; logical shift right the MSB, bit 0 moves to C flag<br />
ror 1,X ; rotate right with the C bit<br />
ror 2,X ; rotate right with the C bit<br />
ror 3,X ; rotate right with the C bit<br />
dbne<br />
end<br />
b,again
Shift a Multi-byte Number (4 of 4)
• Changing a few<br />
bits are often<br />
done in I/O<br />
applications.<br />
• Boolean logic<br />
operation can<br />
be used to<br />
change h a ffew<br />
I/O port pins<br />
easily.<br />
Boolean Logic Instructions (1 of 4)
Boolean Logic Instructions (2 of 4)<br />
• The AND function can be used to clear bits.<br />
•<br />
• Example:<br />
Clears the upper four pins of the I/O or Input/Output port located<br />
at $56. $0056 is for one of I/O ports in 9S12.<br />
ldaa $56 ; A
Boolean Logic Instructions (3 of 4)<br />
The OR function can be used to set bits (change from 0 to 1 and<br />
from a 1 to 1)<br />
Note: X+1= X + 1 1 set bit) X+0= X + 0 X (no<br />
change)<br />
Example: p<br />
Set the upper three pins of the I/O or Input/Output port located at<br />
$56.<br />
ldaa $56 ; A
Boolean Logic Instructions (4 of 4)<br />
The EOR function can be used to toggle bits (change from 0 to 1<br />
and from a 1 to 0)<br />
Note: 0 ⊕ 0 = 0 ; 0 ⊕ 1 = 1<br />
1 ⊕ 0 = 1 ; 1 ⊕ 1 = 0<br />
Example:<br />
Toggle the lower four bits of the I/O or Input/Output port located at<br />
$56 or $0056<br />
ldaa $56 ;A
Program Execution Time (1 of 2)<br />
• The <strong>HCS12</strong> uses the E clock as a timing reference.<br />
• The frequency of the E clock is half of that of the crystal oscillator.<br />
• There are many applications that require the generation of time<br />
delays.<br />
• The creation of a time delay involves two steps:<br />
– Select a sequence of instructions that takes a certain amount of time to<br />
execute.<br />
– Repeat the selected instruction sequence for an appropriate number of<br />
times.<br />
• FFor example, l the th instruction i t ti sequence on th the next t page takes t k 40 E cycles l tto<br />
execute. By repeating this instruction sequence a certain number of times,<br />
any time delay can be created.<br />
– Assume the bus clock frequency is 24 MHz, each cycle = 41.67 ns<br />
– Therefore, the instruction sequence on the next page will take 5 μs to<br />
execute. (35+1+1+3)×41.67 ns = 40 ×41.67 ns = 1.7 μs
Program Execution Time (2 of 2)<br />
For example, p the instruction sequence q below takes 40 E cycles y to execute.<br />
Assume the bus clock frequency is 24 MHz, each cycle =<br />
Therefore, the instruction sequence will take<br />
loop psha ; 2 E cycles<br />
pula ; 3 E cycles<br />
psha ; 2 E cycles<br />
pula ; 3 E cycles<br />
psha ; 2 E cycles<br />
pula ; 3 E cycles<br />
psha ; 2 E cycles<br />
pula ; 3 E cycles<br />
nop ; 1 E cycle<br />
dbne x,loop ; 3 E cycles<br />
24 24 MHz = 1 μs<br />
1 24 MHz ≈ 41.67ns
Example 2.25 Write a program loop to create a delay of 1 ms = 1000 ×1 μs.<br />
Solution: A delay of 1 ms can be created by repeating the previous loop 1000 times.<br />
The following instruction sequence creates a delay of 1 ms.<br />
ldx #1000 ; 2 E cycles<br />
loop psha ; 2 E cycles<br />
pula ; 3 E cycles<br />
psha ; 2 E cycles<br />
pula ; 3 E cycles<br />
psha ; 2 E cycles 21 E cycles<br />
pula ; 3 E cycles 24 E cycles<br />
psha ; 2 E cycles<br />
pula ; 3 E cycles<br />
nop ; 1 E cycle<br />
dbne x, loop ; 3 E cycles<br />
Note: The 2 E cycles for the ldx #1000 is insignificant.<br />
1 1<br />
⎡⎣2+ 1000× ( 21+ 3) ⎤⎦×<br />
= [ 2+ 1000× 24] × ≈1ms<br />
24MHz 24MHz
Example: p Write an instruction<br />
ldab #100 ; 1 E cycle<br />
sequence to create a delay of 1 second. out_loop<br />
in_loop<br />
ldx<br />
psha<br />
#10000 ; 2 E cycles<br />
; 2 E cycles<br />
Solution: By repeating the previous<br />
pula<br />
psha<br />
; 3 E cycles<br />
; 2 E cycles<br />
instruction sequence 100 times times, we can<br />
pula ; 3 E cycles<br />
create a delay of 1 second.<br />
psha<br />
pula<br />
; 2 E cycles<br />
; 3 E cycles<br />
1<br />
{1+ 100× ⎡⎣2+ 10000 × ( 21+ 3) + 3 ⎤⎦}<br />
× ≈1s<br />
24MHz<br />
psha<br />
pula<br />
nop<br />
; 2 E cycles<br />
; 3 E cycles<br />
; 1 E cycle<br />
dbne x, in_loop ; 3 E cycles<br />
dbne b, out_loop ; 3 E cycles<br />
1E cycles for<br />
ldab #100<br />
2E cycles for<br />
ldx #10000<br />
3E cycles for<br />
dbne x, in_loop<br />
Note: # of E cycles for one iteration of<br />
th the out_loop t l = [2 [2+10000×(21+3)+3]<br />
10000 (21 3) 3]<br />
3E cycles for<br />
dbne b, out_loop