Developing Software in Assembly Language
6812 Assembly Language Control Examples
By Jonathan W. Valvano
This article, which discusses assembly language programming,
accompanies the book Embedded Microcomputer Systems: Real Time Interfacing published by Brooks-Cole 1999. This document has four overall
parts
Overview
Syntax (fields, pseudo ops)
Local variables
Examples
Control Examples on the 6812
unsigned 8 bit if then
signed 8 bit if then
unsigned 16 bit if then
signed 16 bit if then
for loops
gadfly loop
while loops
Other Examples
Arithmetic Examples
Shift Examples on the 6812
Stack Usage and Interrupts on the 6812
Interpreters on the 6812
FIFO Queue Examples on the 6812
--------------------------------------------------------------------------------------
Unsigned 8-bit if statements on the 6812
In these examples of unsigned if..else structures, the following
global variables are defined in RAM
G1 rmb 1 Unsigned 8-bit global
G2 rmb 1 Unsigned 8-bit global
G3 rmb 1 Unsigned 8-bit global
G4 rmb 1 Unsigned 8-bit global
In the first example the compare immediate instruction is followed by the unsigned conditional branch to implement the module if(G2 > 100) isGreater();
;Implementation of if(G2 > 100) isGreater();
ldaa G2
cmpa #100
bls L0 ; branch if G2 <= 100
jsr isGreater ; G2 > 100
L0
The second example implements the module if(G2>G1) isGreater();
; Implementation of if (G2>G1) isGreater();
ldaa G2
cmpa G1
bls L1 ; branch if G2<=G1
jsr isGreater ; G2>G1
L1
The third example implements an if else program module.
; Implementation of if (G2>G1) isGreater(); else isLessThanEqual();
ldaa G2
cmpa G1
bhi L2 ; branch if G2>G1
jsr isLessThanEqual ; G2<=G1
bra L3
L2 jsr isGreater ; G2>G1
L3
The fourth example implements a similar if else program module.
; Implementation of if (G2>=G1) isGreaterEqual(); else isLessThan();
ldaa G2
cmpa G1
bhs L4 ; branch if G2>=G1
jsr isLessThan ; G2<G1
bra L5
L4 jsr isGreaterEqual ; G2>=G1
L5
The next example implements a simple compare module.
;Implementation of if (G2>=G1) isEqual(); else isNotEqual();
ldaa G2
cmpa G1
beq L6 ; branch if G1==G2
jsr isNotEqual ; G1!=G2
bra L7
L6 jsr isEqual ; G1==G2
L7
In the next example we implement a compound boolean expression by testing one term at a time.
;Implementation of if ((G2>G1)&&(G4>G3)) isGreater();
ldaa G2
cmpa G1
bls L8 ; branch if G2<=G1
ldaa G4
cmpa G3
bls L8 ; branch if G4<=G3
jsr isGreater ; (G2>G1)&&(G4>G3)
L8
The last example implements a compound if else module.
; Implementation of if ((G2==G1)||(G4>G3)) True(); else False();
ldaa G2
cmpa G1
beq L9 ; true if G2==G1
ldaa G4
cmpa G3
bhi L9 ; true if G4>G3
jsr False ; (G2!=G1)and(G4<=G3)
bra L10
L9 jsr True ; (G2==G1)||(G4>G3)
L10
--------------------------------------------------------------------------------------
Signed 8-bit if statements on the 6812
In these examples of signed if..else structures, the following global variables are defined in RAM
G1 rmb 1 Signed 8-bit global
G2 rmb 1 Signed 8-bit global
G3 rmb 1 Signed 8-bit global
G4 rmb 1 Signed 8-bit global
In the first example the compare immediate instruction is followed by the signed conditional branch to implement the module if(G2 > -100) isGreater();
; Implementation of if(G2 > -1000) isGreater();
ldaa G2
cmpa #-100
ble L0 ; branch if G2 <= -100
jsr isGreater ; G2 > -100
L0
The second example implements the module if(G2>G1) isGreater();
; Implementation of if (G2>G1) isGreater();
ldaa G2
cmpa G1
ble L1 ; branch if G2<=G1
jsr isGreater ; G2>G1
L1
The third example implements an if else program module.
; Implementation of if (G2>G1) isGreater(); else isLessThanEqual();
ldaa G2
cmpa G1
bgt L2 ; branch if G2>G1
jsr isLessThanEqual ; G2<=G1
bra L3
L2 jsr isGreater ; G2>G1
L3
The fourth example implements a similar if else program module.
; Implementation of if (G2>=G1) isGreaterEqual(); else isLessThan();
ldaa G2
cmpa G1
bge L4 ; branch if G2>=G1
jsr isLessThan ; G2<G1
bra L5
L4 jsr isGreaterEqual ; G2>=G1
L5
The next example implements a simple compare module.
;. Implementation of if (G2>=G1) isEqual(); else isNotEqual();
ldaa G2
cmpa G1
beq L6 ; branch if G1==G2
jsr isNotEqual ; G1!=G2
bra L7
L6 jsr isEqual ; G1==G2
L7
In the next example we implement a compound boolean expression by testing one term at a time.
; Implementation of if ((G2>G1)&&(G4>G3)) isGreater();
ldaa G2
cmpa G1
ble L8 ; branch if G2<=G1
ldaa G4
cmpa G3
ble L8 ; branch if G4<=G3
jsr isGreater ; (G2>G1)&&(G4>G3)
L8
The last example implements a compound if else module.
; Implementation of if ((G2==G1)||(G4>G3)) True(); else False();
ldaa G2
cpd G1
beq L9 ; true if G2==G1
ldaa G4
cmpa G3
bgt L9 ; true if G4>G3
jsr False ; (G2!=G1)and(G4<=G3)
bra L10
L9 jsr True ; (G2==G1)||(G4>G3)
L10
--------------------------------------------------------------------------------------
Unsigned 16-bit if statements on the 6812
In these examples of signed if..else structures, the following global variables are defined in RAM
G1 rmb 2 Unsigned 16-bit global
G2 rmb 2 Unsigned 16-bit global
G3 rmb 2 Unsigned 16-bit global
G4 rmb 2 Unsigned 16-bit global
In the first example the compare immediate instruction is followed by the unsigned conditional branch to implement the module if(G2 > 1000) isGreater();
; Implementation of if(G2 > -1000) isGreater();
ldd G2
cpd #1000
bls L0 branch if G2 <= 1000
jsr isGreater G2 > 1000
L0
The second example implements the module if(G2>G1) isGreater();
; Implementation of if (G2>G1) isGreater();
ldd G2
cpd G1
bls L1 ; branch if G2<=G1
jsr isGreater ; G2>G1
L1
The third example implements an if else program module.
; Implementation of if (G2>G1) isGreater(); else isLessThanEqual();
ldd G2
cpd G1
bhi L2 ; branch if G2>G1
jsr isLessThanEqual ; G2<=G1
bra L3
L2 jsr isGreater ; G2>G1
L3
The fourth example implements a similar if else program module.
; Implementation of if (G2>=G1) isGreaterEqual(); else isLessThan();
ldd G2
cpd G1
bhs L4 ; branch if G2>=G1
jsr isLessThan ; G2<G1
bra L5
L4 jsr isGreaterEqual ; G2>=G1
L5
The next example implements a simple compare module.
;. Implementation of if (G2>=G1) isEqual(); else isNotEqual();
ldd G2
cpd G1
beq L6 ; branch if G1==G2
jsr isNotEqual ; G1!=G2
bra L7
L6 jsr isEqual ; G1==G2
L7
In the next example we implement a compound boolean expression by testing one term at a time.
; Implementation of if ((G2>G1)&&(G4>G3)) isGreater();
ldd G2
cpd G1
bls L8 ; branch if G2<=G1
ldd G4
cpd G3
bls L8 ; branch if G4<=G3
jsr isGreater ; (G2>G1)&&(G4>G3)
L8
The last example implements a compound if else module.
; Implementation of if ((G2==G1)||(G4>G3)) True(); else False();
ldd G2
cpd G1
beq L9 ; true if G2==G1
ldd G4
cpd G3
bhi L9 ; true if G4>G3
jsr False ; (G2!=G1)and(G4<=G3)
bra L10
L9 jsr True ; (G2==G1)||(G4>G3)
L10
--------------------------------------------------------------------------------------
Signed 16-bit if statements on the 6812
In these examples of signed if..else structures, the following global variables are defined in RAM
G1 rmb 2 Signed 16-bit global
G2 rmb 2 Signed 16-bit global
G3 rmb 2 Signed 16-bit global
G4 rmb 2 Signed 16-bit global
In the first example the compare immediate instruction is followed by the signed conditional branch to implement the module if(G2 > -1000) isGreater();
; Implementation of if(G2 > -1000) isGreater();
ldd G2
cpd #-1000
ble L0 branch if G2 <= -1000
jsr isGreater G2 > -1000
L0
The second example implements the module if(G2>G1) isGreater();
; Implementation of if (G2>G1) isGreater();
ldd G2
cpd G1
ble L1 branch if G2<=G1
jsr isGreater G2>G1
L1
The third example implements an if else program module.
; Implementation of if (G2>G1) isGreater(); else isLessThanEqual();
ldd G2
cpd G1
bgt L2 branch if G2>G1
jsr isLessThanEqual G2<=G1
bra L3
L2 jsr isGreater G2>G1
L3
The fourth example implements a similar if else program module.
; Implementation of if (G2>=G1) isGreaterEqual(); else isLessThan();
ldd G2
cpd G1
bge L4 ; branch if G2>=G1
jsr isLessThan ; G2<G1
bra L5
L4 jsr isGreaterEqual ; G2>=G1
L5
The next example implements a simple compare module.
; Implementation of if (G2>=G1) isEqual(); else isNotEqual();
ldd G2
cpd G1
beq L6 ; branch if G1==G2
jsr isNotEqual ; G1!=G2
bra L7
L6 jsr isEqual ; G1==G2
L7
In the next example we implement a compound boolean expression by testing one term at a time.
; Implementation of if ((G2>G1)&&(G4>G3)) isGreater();
ldd G2
cpd G1
ble L8 ; branch if G2<=G1
ldd G4
cpd G3
ble L8 ; branch if G4<=G3
jsr isGreater ; (G2>G1)&&(G4>G3)
L8
The last example implements a compound if else module.
; Implementation of if ((G2==G1)||(G4>G3)) True(); else False();
ldd G2
cpd G1
beq L9 ; true if G2==G1
ldd G4
cpd G3
bgt L9 ; true if G4>G3
jsr False ; (G2!=G1)and(G4<=G3)
bra L10
L9 jsr True ; (G2==G1)||(G4>G3)
L10
--------------------------------------------------------------------------------------
While statements on the 6812
In these examples of while modules, the following global variables are defined in RAM. Although these are unsigned 8-bit compares, the examples of the previous sections could be used to implement signed and/or 16-bit comparisions.
G1 rmb 1 Unsigned 8-bit global
G2 rmb 1 Unsigned 8-bit global
This first example implements an unsigned while.
;Implementation of while (G2>G1) isGreater();
L1 ldaa G2
cmpa G1
bls L2 ; stop when G2<=G1
jsr isGreater
bra L1
L2
The 8-bit PC relative branching can be converted to 16 absolute jmps to accomodate larger program segments. See also the section on condition branching far away. The 6812 has the long condition branches.
; Implementation of while (G2>G1) { lots and lots of stuff };
L3 ldaa G2
cmpa G1
lbls L5 ; continue while G2>G1
; more than 128 bytes of object code
; { lots and lots of stuff }
lbra L3
L5
To implement the do while structure, we simply rearrange the order.
;Implementation of do isGreater(); while (G2>G1);
L6 jsr isGreater
ldaa G2
cmpa G1
bhi L6 ; stop when G2<=G1
The 8-bit PC relative branching can be converted to 16 absolute
jmps to accomodate larger program segments.
;Implementation of do { lots and lots of stuff }; while (G2>G1);
L7
; more than 128 bytes of object code
; { lots and lots of stuff }
ldd G2
cpd G1
lbhi L7 ; stop when G2<=G1
--------------------------------------------------------------------------------------
Gadfly Loops on the 6812
A very common application of a while loop is waiting for a particular bit in an I/O register to be set. The following example waits for bit 2 of PORTA to be set.
; Implementation of while((PORTA&0x40)==0){};
PORTA equ 0
L9 brclr PORTA,#$04,L9
;Implementation of while((PORTA&0x04)==0){};
PORTA equ 0
L9 ldaa PORTA
bita #$04
beq L9
;Implementation of while((PORTA&0x04)==0){};
PORTA equ 0
ldaa #$04
L9 bita PORTA
beq L9
#define RDRF 0x20 // Receive Data Register Full Bit
// Wait for new serial port input, return ASCII code for key typed
char InChar(void){
while ((SC0SR1 & RDRF) == 0){};
return(SC0DRL);}
; Read 8 bits from serial port
; Return 8-bit byte in RegA
RDRF equ $20
InChar ldaa SC0SR1 ; Reg A has the serial status
anda #RDRF ; new input available?
beq InChar ; wait for RDRF to be set
ldaa SC0DRL ; read ASCII character
rts
#define TDRE 0x80 // Transmit Data Register Empty Bit
// Wait for buffer to be empty, output ASCII to serial port
void OutChar(char data){
while ((SC0SR1 & TDRE) == 0){};
SC0DRL = data;
}
; Write 8 bits to serial port
; Input 8-bit byte in RegA
TDR equ $80
OutChar ldab SC0SR1 ; Reg B has the serial status
andb #TDRE ; output channel ready for transmission?
beq OutChar ; wait for TDRE to be set
staa SC0DRL ; write ASCII character
rts
--------------------------------------------------------------------------------------
For loop statements on the 6812
In these examples of for loop modules, the following global variables are defined in RAM. Many microcomputers have special op codes to facilate the implementation of 8-bit for loops.
I rmb 1 Unsigned 8-bit global
J rmb 2 Unsigned 16-bit global
It is efficient to implement the for loop with a decrementing
index. The first implementation places the 8-bit index in a register
; Implementation of for(I=100;I>0;I--) process();
ldab #100 ; I=100
L1 jsr process
dbne B,L1 ; I=I-1
If a register is not available, this same for loop can be implemented
by placing I in the global variable.
; Another implementation of for(I=100;I>0;I--) process();
movb #100,I ; I=100
L2 jsr process
dec I ; I=I-1
bne L21
If a register is not available and we wish to make it reentrant,
this same for loop can be implemented by placing I as a local
variable on the stack.
; A stack implementation of for(I=100;I>0;I--) process();
movb #100,1,-SP ; allocate, I=100
L3 jsr process
dec 0,sp ; I=I-1
bne L3
leas 1,sp ; deallocate
The following example is more general.
; A global variable implementation of for(J=100;J<1000;J++) { process();}
movw #100,J ; J=100
L4 ldd J
cpd #1000
bhs L5 ; quit if J_1000
jsr process
ldd J ; J=J+1
addd #1
std J
bra L4
L5
If a register can be used, the for loop will be more efficient.
;A register implementation of for(J=100;J<1000;J++) { process();}
ldd #100 ; J=100
L6 cpd #1000
bhs L7 ; quit if J_1000
jsr process
addd #1 ; J=J+1
bra L6
L7
This document has four overall parts
Overview
Syntax (fields, pseudo ops)
Local variables
Examples