Introduction to Embedded Microcomputer Systems Lecture 7.2
“I’ve traveled the length and breadth of this country and talked with the best people, and I can assure you that data processing is a fad that won’t last out the year. ”
Editor in charge of business books for Prentice Hall, 1957
3.3. Introduction to programming
3.3.1. Memory and register transfer operations
The 8-bit load instructions
ldaa #w RegA=w
ldaa U RegA=[U]
ldab #w RegB=w
ldab U RegB=[U]
Condition code bits are set
N: result is negative N=R7
Z: result is zero
V: signed overflow V=0
The 16-bit load instructions
ldd #W RegD=W
ldd U RegD={U}
lds #W RegSP=W
lds U RegSP={U}
ldx #W RegX=W
ldx U RegX={U}
ldy #W RegY=W
ldy U RegY={U}
Condition code bits are set
N: result is negative N=R15
Z: result is zero
V: signed overflow V=0
The memory to memory move instructions, set no flags.
movb #w,addr [addr]=w
movb addr1,addr2 [addr2]=[addr1]
movw #W,addr {addr}=W
movw addr1,addr2 {addr2}={addr1}
The 8-bit store instructions
staa U [U]=RegA
stab U [U]=RegB
Condition code bits are set
N: result is negative N=R7
Z: result is zero
V: signed overflow V=0
The 16-bit store instructions
std U {U}=RegD
sts U {U}=RegSP
stx U {U}=RegX
sty U {U}=RegY
Condition code bits are set
N: result is negative N=R15
Z: result is zero
V: signed overflow V=0
The transfer operations
xgdx swap RegD and RegX
xgdy swap RegD and RegY
clc clear carry bit, C=0
cli enable interrupts, I=0
clv clear overflow bit, V=0
sec set carry bit, C=1
sei disable interrupts, I=1
sev set overflow bit, V=1
tap transfer A to CC
tpa transfer CC to A
3.3.2. Arithmetic operations
8-bit addition
These instructions work for both signed and unsigned data.
adda #w RegA=RegA+w
adda U RegA=RegA+[U]
addb #w RegB=RegB+w
addb U RegB=RegB+[U]
Condition code bits are set after R=X+M,
N: result is negative N=R7
Z: result is zero
V: signed overflow
V=X7•M7•not(R7)+not(X7)•not(M7)•R7
C: unsigned overflow
C=X7•M7+M7•not(R7)+not(R7)•X7
16-bit addition
These instructions work for both signed and unsigned data.
addd #W RegD=RegD+W
addd U RegD=RegD+{U}
Condition code bits are set after R=D+M.
N: result is negative N=R15
Z: result is zero
V: signed overflow
V=D15•M15•not(R15)+not(D15)•not(M15)•R15
C: unsigned overflow
C=D15•M15+M15•not(R15)+not(R15)•D15
8-bit subtraction
These instructions work for both signed and unsigned data.
cmpa #w RegA-w
cmpa U RegA-[U]
cmpb #w RegB-w
cmpb U RegB-[U]
suba #w RegA=RegA-w
suba U RegA=RegA-[U]
subb #w RegB=RegB-w
subb U RegB=RegB-[U]
tsta RegA-0
tstb RegB-0
Condition code bits are set after R=X-M
N: result is negative N=R7
Z: result is zero
V: signed overflow
V=X7•not(M7)•not(R7)+not(X7)•M7•R7
C: unsigned overflow
C=not(X7)•M7+M7•R7+R7•not(X7)
16-bit subtraction
These instructions work for both signed and unsigned data.
cpd #W RegD-W
cpd U RegD-{U}
cpx #W RegX-W
cpx U RegX-{U}
cpy #W RegY-W
cpy U RegY-{U}
subd #W RegD=RegD-W
subd U RegD=RegD-{U}
Condition code bits are set after R=X-M
N: result is negative N=R15
Z: result is zero
V: signed overflow
V=X15•not(M15)•not(R15)+not(X15)•M15•R15
C: unsigned overflow
C=not(X15)•M15+M15•R15+R15•not(X15)
The increment and decrement instructions,
These instructions work for both signed and unsigned data.
The Z bit is set if the result is zero.
deca RegA=RegA-1
decb RegA=RegA-1
dex RegX=RegX-1
dey RegY=RegY-1
inca RegA=RegA+1
incb RegB=RegB+1
inx RegX=RegX+1
iny RegY=RegY+1
mul an 8-bit by 8-bit into 16-bit unsigned multiply
Figure 3.13. The mul instruction takes two 8-bit inputs and generates a 16-bit product.
Condition code bits are set after R=A*B.
C: R7, set if bit 7 of 16-bit result is one
Checkpoint 3.13: Prove the mul instruction can’t overflow.
Let N and M be 8-bit unsigned locations. M=3*N.
ldaa N
ldab #3
mul RegD=3*N
cmpa #0
beq ok
ldab #255 overflow
OK stab M
idiv performs 16-bit by 16-bit unsigned divide
Figure 3.14. The idiv instruction takes two 16-bit inputs and generates a 16-bit quotient and a 16-bit remainder.
Condition code bits are set after quotient=dividend/divisor.
Z: result is zero,
V: 0
C: divide by zero,
C=not(X15)•not(X14)•...•not(X2)•not(X1)•not(X0)
Let N and M be 16-bit unsigned locations. M=N/15.
ldd N D=N (between 0 and 65535)
ldx #15
idiv X=N/15 (between 0 and 4369)
stx M
Checkpoint 3.14: Give a single mathematical equation relating the dividend, divisor, quotient, and remainder. This equation gives a unique solution as long as you assume the remainder is strictly less than the divisor.
fdiv performs a 16-bit by 16-bit unsigned divide
Figure 3.15. The fdiv instruction takes two 16-bit inputs and generates a 16-bit quotient and a 16-bit remainder.
Condition code bits are set after R=(65536*D)/X.
Z: result is zero,
V: overflow if RegX ≤ RegD, result >$FFFF
C: divide by zero,
Let N and M be 16-bit unsigned locations. M=12.34*N.
We approximate 12.34 by 65536/5311.
ldd N
ldx #5311
fdiv RegX=(65536*N)/5311
stx M
Checkpoint 3.15: Let N and M be 8-bit unsigned locations. Write assembly code to implement M=(7*N)/31.
3.3.3. Shift operations
The N bit is set if the result is negative.
The Z bit is set if the result is zero.
The V bit is set on a signed overflow, change in the sign bit.
The C bit is the carry out after the shift.
asla RegA=RegA*2 (same as lsla)
aslb RegB=RegB*2 (same as lslb)
asld RegD=RegD*2 (same as lsld)
lsla RegA=RegA*2 (same as asla)
lslb RegB=RegB*2 (same as aslb)
lsld RegD=RegD*2 (same as asld)
asra RegA=RegA/2 (signed)
asrb RegB=RegB/2 (signed)
asrd RegD=RegD/2 (signed)
lsra RegA=RegA/2 (unsigned)
lsrb RegB=RegB/2 (unsigned)
lsrd RegD=RegD/2 (unsigned)
rola RegA=rol(RegA) (C←A7←…←A0←C)
rolb RegB=rol(RegB) (C←B7←…←B0←C)
rora RegA=ror(RegA) (C→A7→…→A0→C)
rorb RegB=ror(RegB) (C→B7→…→B0→C)
3.3.4. Logical operations
The N bit will be set is the result is negative.
The Z bit will be set if the result is zero.
Clear V=0 bit.
anda #w RegA=RegA&w
anda U RegA=RegA&[U]
andb #w RegB=RegB&w
andb U RegB=RegB&[U]
bita #w RegA&w
bita U RegA&[U]
bitb #w RegB&w
bitb U RegB&[U]
coma RegA=$FF-RegA, RegA=~RegA
comb RegB=$FF-RegB, RegB=~RegB
eora #w RegA=RegA ^ w
eora U RegA=RegA ^ [U]
eorb #w RegB=RegB ^ w
eorb U RegB=RegB ^ [U]
oraa #w RegA=RegA | w
oraa U RegA=RegA | [U]
orab #w RegB=RegB | w
orab U RegB=RegB | [U]
3.3.5. Subroutines and the stack
classical definition of the stack
· push saves data on the top of the stack,
· pull removes data from the top of the stack
· stack implements last in first out (LIFO) behavior
· stack pointer (SP) points to top element
many uses of the stack
· temporary calculations
· subroutine (function) return addresses
· subroutine (function) parameters
· local variables
Initially, the stack is empty
lds #$0C00 for MC68HC812A4 (book)
lds #$4000 for 9S12C32 (class, lab)
ldaa #1
psha ; push 1 on the stack
ldaa #2
psha ; push 2 on the stack
ldaa #3
psha ; push 3 on the stack
At this point if one were to pull from the stack execute pula, the 3 would be returned
the 2 would now be on the top of the stack
Figure 3.17. The stack holding two elements, with the 2 on top.
The push and pull instructions
psha push Register A on the stack
pshb push Register B on the stack
pshx push Register X on the stack
pshy push Register Y on the stack
des S =S-1 (reserve space)
pula pull from stack into A
pulb pull from stack into B
pulx pull from stack into X
puly pull from stack into Y
ins S=S+1 (discard top of stack)
The following are important instructions
tsx transfer S to X
tsy transfer S to Y
txs transfer X to S
tys transfer Y to S
we use the term subroutine all functions or procedures
· whether or not they return a value
· develop modular software
· called by either bsr or jsr
· subroutine returns using rts
org $4000
main lds #$4000 ; initialize stack
clra
loop bsr sub ; branch to subroutine
bra loop
; Purpose: increment a number
; Input: RegA, range 0 to 255
; Output: RegA=Input+1
; Errors: Will overflow if input is 255
sub inca ; adds one to Input
rts
org $fffe
fdb main
Program 3.1. Simple program showing how to use the bsr and rts instructions to implement a subroutine.
We begin the study by looking at the listing file.
$4000 org $4000
$4000 CF4000 [2]( 0){OP }main lds #$4000
$4003 87 [1]( 2){O } clra
$4004 0702 [4]( 3){PPPS }loop bsr sub
$4006 20FC [3]( 7){PPP } bra loop
$4008 42 [1](10){O }sub inca
$4009 3D [5](11){UfPPP} rts
Program 3.2. 6812 Assembly listing of Program 3.1.
Execute the lds instruction
Opcode fetch R 0x4000 0xCF from EEPROM
Operand fetch R 0x4001 0x40 from EEPROM
Operand fetch R 0x4002 0x00 from EEPROM
Execute the clra instruction
Opcode fetch R 0x4003 0x87 from EEPROM
Execution the bsr instruction
Opcode fetch R 0x4004 0x07 from EEPROM
Operand fetch R 0x4005 0x02 from EEPROM
Stack store lsbW 0x3FFF 0x06 to RAM
Stack store msbW 0x3FFE 0x40 to RAM
Figure 3.18. The stack before and after execution of the bsr instruction.
Execute the inca instruction
Opcode fetch R 0x4008 0x42 from EEPROM
Execute the rts instruction
Figure 3.19. The stack before and after execution of the rts instruction.
3.3.6. Branch operations
bcc place go if C=0
bcs place go if C=1
beq place go if Z=1
bne place go if Z=0
bmi place go if N=1
bpl place go if N=0
bvc place go if V=0
bvs place go if V=1
bra place go always
brn place go never
jmp place go always, ext addr
must follow a subtract compare or test instruction, such as
suba subb sbca sbcb subd
cba cmpa cmpb cpd
tsta tstb tst
signed branches, branch if
bge place greater than or equal to
if (N^V)=0
i.e., (~N•V+N•~V)=0
bgt place greater than
if (Z+N^V)=0
i.e., (Z+~N•V+N•~V)=0
ble place less than or equal to
if (Z+N^V)=1
i.e., (Z+~N•V+N•~V)=1
blt place less than
if (N^V)=1
i.e., (~N•V+N•~V)=1
unsigned branches, branch if
bhs place greater than or equal to
if C=0, same as bcc
bhi place greater than
if C+Z=0
blo place less than
if C=1, same as bcs
bls place less than or equal to
if C+Z=1
it is important to know
· precision (e.g., 8-bit, 16-bit)
· format (e.g., unsigned, signed)
It takes three steps
1. read the first value into a register
2. compare the first value with the second value
3. conditional branch
When testing for equal or not equal
· doesn’t matter whether signed or unsigned
· still matters if 8-bit or 16-bit
· doesn’t matter about load and compare order
8-bit if-then compare to zero examples
Assume G is an 8-bit global variable, signed or unsigned
C code / assembly codeif(G == 0){
♪♫♪♫♫
} / ldaa G
bne next
♪♫♪♫♫
next
if(G != 0){
♪♫♪♫♫
} / ldaa G
beq next
♪♫♪♫♫
next
8-bit if-then signed compare to zero examples
Assume sG is a signed 8-bit global variable
C code / assembly codeif(sG >= 0){
♪♫♪♫♫
} / ldaa sG
bmi next
♪♫♪♫♫
next
if(sG 0){
♪♫♪♫♫
} / ldaa sG
bpl next
♪♫♪♫♫
next
8-bit if-then compare examples
Assume G1 G2 are 8-bit global variables, signed or unsigned
C code / assembly codeif(G2 == G1){
♪♫♪♫♫
} / ldaa G2
cmpa G1
bne next
♪♫♪♫♫
next
if(G2 != G1){
♪♫♪♫♫
} / ldaa G2
cmpa G1
beq next
♪♫♪♫♫
next
Compare 8-bit versus 16-bit conditionals
Assume G1 G2 are 8-bit global variables, signed or unsigned
Assume H1 H2 are 16-bit global variables, signed or unsigned
C code / assembly codeif(G2 == G1){
♪♫♪♫♫
} / ldab G2
subb G1
bne next
♪♫♪♫♫
next
if(H2 == H1){
♪♫♪♫♫
} / ldy H2
cpy H1
bne next
♪♫♪♫♫
next
Common error. It is an error to use an 8-bit comparison to test two 16-bit values.
it is important to know
· precision (e.g., 8-bit, 16-bit)
· format (e.g., unsigned, signed)
· unsigned, bhi blo bhs and bls
· signed, bgt bls bge and ble
It takes three steps
1. read the first value into a register
2. compare the first value with the second value
3. conditional branch
Compare the four possible inequalities
Assume uG is a unsigned 8-bit global variable
C code / assembly codeif(uG 5){
♪♫♪♫♫
} / ldaa uG
cmpa #5
bls next
♪♫♪♫♫
next
if(uG >= 5){
♪♫♪♫♫
} / ldaa uG
cmpa #5
blo next
♪♫♪♫♫
next
if(uG 5){
♪♫♪♫♫
} / ldaa uG
cmpa #5
bhs next
♪♫♪♫♫
next
if(uG <= 5){
♪♫♪♫♫
} / ldaa uG
cmpa #5
bhi next
♪♫♪♫♫
next
Mark W. Welker ( From Jonathan W. Valvano)